Json: How to prevent alphabetical sorting of data?

Created on 6 Sep 2017  路  9Comments  路  Source: nlohmann/json

Hi Niels,

Thanks a lot for writing your "JSON for Modern C++".

How do I save the JSON data to file while retaining it's original order (after opening and editing from an existing data.json file) such that the saved objects and their keys are subsequently not sorted alphabetically upon saving the data?

This is how I'd like the json data to be saved to file, as it was originally (not alphabetically sorted):-

image

鈥婬owever after saving to file, the data ends up alphabetically sorted (below).

image

Is there a way to prevent the json data being alphabetically sorted?

Much thanks. Greg

question release item new feature duplicate proposed fix

Most helpful comment

@nlohmann

It is a pity to me that a JSON object does not preserve the order of elements.

This is a highly desirable feature. For example, specifying parameters -- there is often a natural ordering.

While the standard does not guarantee to preserve order, nor does it guarantee to alphabetise.
Your implementation would remain fully standards compliant by preserving order.

This is a very beautiful library. I think this is why the community is reluctant to whinge, as am I.

The ability to retain order would certainly beautify the function -- whether or not this would be nullified by the uglification to the code base, you are in the best position to see this.

If it is possible to preserve order with some minor modification, a more complete documentation on how to do this would be most helpful!

(I am linking your library to my development team as gold-standard example of how to architect a third-party library).

All 9 comments

This is covered in the README https://github.com/nlohmann/json#notes

Duplicate: #106 #424 #660.

@nlohmann

It is a pity to me that a JSON object does not preserve the order of elements.

This is a highly desirable feature. For example, specifying parameters -- there is often a natural ordering.

While the standard does not guarantee to preserve order, nor does it guarantee to alphabetise.
Your implementation would remain fully standards compliant by preserving order.

This is a very beautiful library. I think this is why the community is reluctant to whinge, as am I.

The ability to retain order would certainly beautify the function -- whether or not this would be nullified by the uglification to the code base, you are in the best position to see this.

If it is possible to preserve order with some minor modification, a more complete documentation on how to do this would be most helpful!

(I am linking your library to my development team as gold-standard example of how to architect a third-party library).

I know that preserving the insertion order would be also compliant, but would also be more work in my case. However, the README states some solutions:

By default, the library does not preserve the insertion order of object elements. This is standards-compliant, as the JSON standard defines objects as "an unordered collection of zero or more name/value pairs". If you do want to preserve the insertion order, you can specialize the object type with containers like tsl::ordered_map (integration) or nlohmann::fifo_map (integration).

Unfortunaltely, this does not preserve the order in all cases:

soti@pc18015:~/dev/json$ cat json2.cpp
// Compile with: g++ -g -O0 -std=c++11 -o json2 json2.cpp
#include <iostream>
#include "./fifo_map/src/fifo_map.hpp"
#include "./nlohmann_json/single_include/nlohmann/json.hpp"

// See https://github.com/nlohmann/json#notes
// See https://github.com/nlohmann/json/issues/485#issuecomment-333652309
// A workaround to give to use fifo_map as map, we are just ignoring the 'less' compare
template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
using my_json = nlohmann::basic_json<my_workaround_fifo_map>;


int main(void)
{
    std::string s1 = "{\"c\": 1, \"b\": 2, \"a\": 3}";
    my_json v = nlohmann::json::parse(s1);
    std::cout << "original = " << s1 << std::endl;
    std::cout << "parsed = " << v << std::endl;
    std::cout << "dumped = " << v.dump() << std::endl;

    return 0;
}


soti@pc18015:~/dev/json$ ./json2
original = {"c": 1, "b": 2, "a": 3}
parsed = {"a":3,"b":2,"c":1}
dumped = {"a":3,"b":2,"c":1}
soti@pc18015:~/dev/json$

@tilman22 have you found a work around to preserve the keys order if we were to parse from string like your example above?

My workaround was to use RapidJson instead.
RapidJson was designed to keep the property order.

I think your issue was in this line:

     my_json v = nlohmann::json::parse(s1);
````

You are calling ```json::parse``` which gives you the non-order behavior first. 

Instead try:
my_json v = my_json::parse(s1);

```

To be fixed with #2258.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zkelo picture zkelo  路  3Comments

dcube9 picture dcube9  路  3Comments

zhishupp picture zhishupp  路  4Comments

sqwunkly picture sqwunkly  路  3Comments

mlund picture mlund  路  4Comments