Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to prevent alphabetical sorting of data? #727

Closed
sqwunkly opened this issue Sep 6, 2017 · 11 comments · Fixed by #2258
Closed

How to prevent alphabetical sorting of data? #727

sqwunkly opened this issue Sep 6, 2017 · 11 comments · Fixed by #2258
Assignees
Labels
kind: question release item: ✨ new feature solution: duplicate the issue is a duplicate; refer to the linked issue instead solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Milestone

Comments

@sqwunkly
Copy link

sqwunkly commented Sep 6, 2017

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

​However 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

@gregmarr
Copy link
Contributor

gregmarr commented Sep 6, 2017

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

@nlohmann
Copy link
Owner

nlohmann commented Sep 6, 2017

Duplicate: #106 #424 #660.

@nlohmann nlohmann added the solution: duplicate the issue is a duplicate; refer to the linked issue instead label Sep 6, 2017
@p-i-
Copy link

p-i- commented Jan 22, 2019

@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).

@nlohmann
Copy link
Owner

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).

@tilman22
Copy link

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$

@tuananh
Copy link

tuananh commented Jun 12, 2019

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

@tilman22
Copy link

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

@jaredgrubb
Copy link
Contributor

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); 

@nlohmann nlohmann added release item: ✨ new feature solution: proposed fix a fix for the issue has been proposed and waits for confirmation labels Jul 11, 2020
@nlohmann nlohmann self-assigned this Jul 11, 2020
@nlohmann nlohmann added this to the Release 3.8.1 milestone Jul 11, 2020
@nlohmann
Copy link
Owner

To be fixed with #2258.

@simon-videoloft
Copy link

Feels like a huge flaw in the design of this library. Of course data order should be preserved - jumbling up the order just because the standard doesn't require ordered data is nonsense.

@nlohmann
Copy link
Owner

Feels like a huge flaw in the design of this library. Of course data order should be preserved - jumbling up the order just because the standard doesn't require ordered data is nonsense.

Ooof, thanks. You can use ordered_json for this. And I think the documentation is clear about the rationale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question release item: ✨ new feature solution: duplicate the issue is a duplicate; refer to the linked issue instead solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants