Object Order¶
The JSON standard defines objects as "an unordered collection of zero or more name/value pairs". As such, an implementation does not need to preserve any specific order of object keys.
Default behavior: sort keys¶
The default type nlohmann::json
uses a std::map
to store JSON objects, and thus stores object keys sorted alphabetically.
Example
#include <iostream>
#include "json.hpp"
using json = nlohmann::json;
int main()
{
json j;
j["one"] = 1;
j["two"] = 2;
j["three"] = 3;
std::cout << j.dump(2) << '\n';
}
Output:
{
"one": 1,
"three": 3,
"two": 2
}
Alternative behavior: preserve insertion order¶
If you do want to preserve the insertion order, you can try the type nlohmann::ordered_json
.
Example
#include <iostream>
#include <nlohmann/json.hpp>
using ordered_json = nlohmann::ordered_json;
int main()
{
ordered_json j;
j["one"] = 1;
j["two"] = 2;
j["three"] = 3;
std::cout << j.dump(2) << '\n';
}
Output:
{
"one": 1,
"two": 2,
"three": 3
}
Alternatively, you can use a more sophisticated ordered map like tsl::ordered_map
(integration) or nlohmann::fifo_map
(integration).
Notes on parsing¶
Note that you also need to call the right parse
function when reading from a file. Assume file input.json
contains the JSON object above:
{
"one": 1,
"two": 2,
"three": 3
}
Right way
The following code correctly calls the parse
function from nlohmann::ordered_json
:
std::ifstream i("input.json");
auto j = nlohmann::ordered_json::parse(i);
std::cout << j.dump(2) << std::endl;
The output will be:
{
"one": 1,
"two": 2,
"three": 3
}
Wrong way
The following code incorrectly calls the parse
function from nlohmann::json
which does not preserve the insertion order, but sorts object keys. Assigning the result to nlohmann::ordered_json
compiles, but does not restore the order from the input file.
std::ifstream i("input.json");
nlohmann::ordered_json j = nlohmann::json::parse(i);
std::cout << j.dump(2) << std::endl;
The output will be:
{
"one": 1,
"three": 3
"two": 2,
}