How to iterate over a JSON in JSON for modern c++
The nlohmann json library promotes itself as "JSON for modern C++" and aspires to behave "just like an STL container". There is, however, no container in the C++ standard library that is both "vector-like" and "map-like", and that supports both begin/end iterators over values, and begin/end iterators over key/value pairs. So something new is needed.
nlohmann's original solution was to copy jsoncpp's approach, which supports begin/end iterators for json arrays, and adds a distinctly unstandard key()
function to the iterator to also support json objects. So you could write
for (auto it = RecentFiles.begin(); it != RecentFiles.end(); ++it){ std::cout << it.key() << "\n"; std::cout << (*it)["Name"].get<std::string>() << "\n"; std::cout << (*it)["Last modified"].get<std::string>() << "\n";}
But being an unstandard way of iterating over key/values, this doesn't have standard library support for range based for loops over key/values.
nlohmann later added the json::items()
function that does support iteration over json objects with standard iterators, and which does have standard library support for range based for loops, viz.
int main(){ json RecentFiles; RecentFiles["1"]["Name"] = "test1.txt"; RecentFiles["1"]["Last modified"] = "monday"; RecentFiles["1"]["Score"] = 5.0f; RecentFiles["2"]["Name"] = "test2.txt"; RecentFiles["2"]["Last modified"] = "tuesday"; RecentFiles["2"]["Score"] = 5.0f; for (const auto& item : RecentFiles.items()) { std::cout << item.key() << "\n"; for (const auto& val : item.value().items()) { std::cout << " " << val.key() << ": " << val.value() << "\n"; } } std::cout << "\nor\n\n"; for (const auto& item : RecentFiles.items()) { std::cout << item.key() << "\n"; std::cout << " " << item.value()["Name"].get<std::string>() << "\n"; std::cout << " " << item.value()["Last modified"].get<std::string>() << "\n"; std::cout << " " << item.value()["Score"].get<double>() << "\n"; }}
Output:
1 Last modified: "monday" Name: "test1.txt" Score: 5.02 Last modified: "tuesday" Name: "test2.txt" Score: 5.0or1 test1.txt monday 52 test2.txt tuesday 5