I'm trying to iterate over a json input file containing an unknown number of molecules (see below). For each of these the key is the name which I currently have found no way to extract. Is this possible?
Code:
#include <faunus/json.hpp>
#include <iostream>
#include <fstream>
/*
* minimal.json:
* {
* "moleculelist" : {
* "salt" : { "atoms":"Na Cl", "atomic":true, "Ninit":1 },
* "water" : { "atoms":"H H O", "atomic":false, "Ninit":55 }
* }
* }
*/
using json = nlohmann::json;
int main() {
std::ifstream f("minimal.json");
if (f) {
json j;
j << f;
if ( ! j["moleculelist"].empty() )
for ( auto &mol : j["moleculelist"] )
if ( mol.is_object() ) {
// how to get entry keys? (i.e. "salt", "water", etc.)
for ( auto &i : mol )
std::cout << i << "\n";
}
}
}
Found one solution,
for ( auto &mol : j["moleculelist"].get<json::object_t>() ) { ... }
which returns a std::map where first and second represents name and value. Don't know if this extra complication warrants a name() function in basic_json or not.
Unfortunately, there is no way for a JSON value to "know" whether it is stored in an object, and if so under which key. All you can do is to use the json::iterator class which has a key() and value() member function to access the key and the value when you iterate over an object.
For your code:
for (auto it = j["moleculelist"].begin(); it != j["moleculelist"].end(); ++it)
{
std::cout << it.key() << " | " << it.value() << "\n";
}
(Here, it would be of type json::iterator.) This prints
salt | {"Ninit":1,"atomic":true,"atoms":"Na Cl"}
water | {"Ninit":55,"atomic":false,"atoms":"H H O"}
I hope this helps!
This will work nicely, thanks!
for ( auto it: j["moleculelist"].items() )
{
std::cout << it.key() << " | " << it.value() << "\n";
}
Most helpful comment