Qt World Summit: Submit your Presentation


About QJsonObject: the order of the inserted items is not preserved



  • I have checked the forum, there is no such topic. So I start this one.

    For example:
    QJsonObject JObject;
    JObject["Department"] = QString("xxx");
    JObject["Chairman"] = QString("xxx");
    JObject["Assignment"] = QString("xxx");
    JObject["Backup"] = QString("xxx");

    then write it to a json file, and I get
    {
    "Assignment" : "xxx"
    "Backup" : "xxx"
    "Chairman" : "xxx"
    "Department" "xxx"
    }

    It is not the order by which I put the items in.

    I know it is not a bug because JSON standard does not require the order of the output to be the same as the order of the input. However, since json file is designed to be human-readable, we use it to store valuable information (algorithm output), and often we need to read the files.

    We could invent a file format, but we need to exchange file with other people to communicate over internet. It is better to use a standard file, and we use json.

    Java has a solution: use LinkedHashMap as input, which is mentioned in the link

    http://stackoverflow.com/questions/17229418/jsonobject-why-jsonobject-changing-the-order-of-attributes

    Other people may also need order-preserved output for other reasons . And someone mentioned that "V8, for instance, keeps all keys in insertion order except for keys that can be parsed as unsinged 32-bit integers." in the link

    http://stackoverflow.com/questions/7214293/is-the-order-of-elements-in-a-json-list-maintained

    In summary, could Qt provide a method/option that can preserve the input order?

    Thank you very much.


  • Moderators

    I don't think this functionality should be provided by Qt. The standard says the order is unspecified, so you shouldn't rely on it, even if some library or language provides it. What if suddenly your code that relies on it receives a json from another source that doesn't have this guarantee or, for example, reverses that order?
    I would say if you need to preserve order use arrays instead of objects. They're guaranteed to do so.



  • Thanks for the reply.

    in my case:
    My computer program can read out of order json, and it does not rely on any order. However, human (me and others) can not read out of order json. So we need to preserve the output order for human readers. JSON advocates itself as "human-readable" against XML, and clearly the order matters for the human-readability. By doing so, we do not violate JSON standard, and we make it better.

    in other cases:
    according to stackoverflow, v8 preserves the order. I guess in that way json file can be easily checked by human users, e.g., a file with records form database.

    In summary, it is all about human-readability.


  • Moderators

    Well I would guess that json object is implemented as some sort of map, which usually don't care about insertion order and changing it into something else might have performance penalties.

    From what I see that V8 parser keeps the order only partially and I wouldn't hold my breath that it will stay like that forever. Certainly they don't guarantee it. It's probably an artifact of their implementation. XML doesn't care about the order of elements either(without some sort of schema or DTD).

    It's not like Qt implementation makes a mess. I would argue that alphabetical order is pretty human-readable and certainly a lot friendlier to the likes of source control systems (eg. look what mess are xml Visual Studio project files).

    Are arrays an alternative for you or is the format already set in stone?
    Anyway, I'm not opposing. I just don't see it as that much of an issue. If you want to you can always make a feature request "here":https://bugreports.qt-project.org



  • It would be nice if this were user-configurable, but judging from the comment in the source code here, it is definitely part of the design to keep object elements sorted by key:

    https://code.woboq.org/qt5/qtbase/src/corelib/serialization/qjson_p.h.html#473


  • Lifetime Qt Champion

    Since json has no restriction on the order (= is unordered) I don't see why this would be needed.



  • @Christian-Ehrlicher From what I have seen in various places on the internet, many people seem to miss having this option. It is also worth noting that preserving the input order of elements would not make an implementation of the JSON standard non-compliant. As a work-around, if one has control over the format, one could name the keys in such as way that they would be sorted as desired.

    Personally, I find it much more confusing that the elements of a single JSON array can be of different types, whereas in most other languages, the array elements must be all of the same type.



  • @Robert-Hairgrove
    Purely OoI, can you name any non-Qt JSON serializer which does this "retain input order" or "save in alphabetical order"?

    I also fear it could lull developers into false code. They might rely on this ordering while reading from JSON files created from Qt, and then come a cropper when they get a legal JSON file from another source which does not do so.


  • Moderators

    @Robert-Hairgrove said in About QJsonObject: the order of the inserted items is not preserved:

    @Christian-Ehrlicher From what I have seen in various places on the internet, many people seem to miss having this option. It is also worth noting that preserving the input order of elements would not make an implementation of the JSON standard non-compliant. As a work-around, if one has control over the format, one could name the keys in such as way that they would be sorted as desired.

    The implementation does affect performance. If the map is always sorted by key, then a key lookup can use a binary search which has O(log n) complexity. If sorting by insertion order is allowed, then key lookup has to use a linear search which has O(n) complexity.

    Personally, I find it much more confusing that the elements of a single JSON array can be of different types, whereas in most other languages, the array elements must be all of the same type.

    Think of it as a std::vector<std::variant>.

    Anyway, JSON arrays are based on JavaScript arrays, which allow mixed types: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

    Python Lists also allow mixed types.



  • @JKSH said in About QJsonObject: the order of the inserted items is not preserved:

    The implementation does affect performance.

    True, but I don't think that is what the OP or @Robert-Hairgrove is asking about/for. They are talking only about the serialization to file ordering, for inspection, not the in-memory behaviour. They would be happy if the former could be controlled/altered without impacting the latter. Mind you, I don't know if that is practical/possible. I believe the OP at least was asking for insertion order to be maintained....


Log in to reply