I want to store multiple images (with different attributes) per tile-type and find the correct json object that matches a key.
like:
Type floor, orientation: center
for (auto it : TileDataJSON["floor"].items()) {
cout << "key " << it.key() << " and val " <<it.value();
}
Output:
key 0 and val {"image":"floor_0.png","orientation":"flat"}
key 1 and val {"image":"floor_center.png","orientation":"center"}
key 2 and val {"image":"floor_n.png","orientation":"n"}
....
Which makes sense.
If i try to access
TileDataJSON["floor"][it.key()]
i get an exception. ( i think it's because it.key is a string an not an int...
My (simplified) JSON File looks like this:
{
"floor": [
{
"image": "floor_0.png",
"orientation": "flat"
},
{
"image": "floor_center.png",
"orientation": "center"
}
]
}
What is the correct way to find the correct object of a type by an attribute?
After trying to figure out a way to do that, i came up with following solution:
std::string findOrientation = "center";
size_t idx = 0;
while (!TileDataJSON["floor"][idx].is_null())
{
for (auto &it : TileDataJSON["floor"][idx].items())
{
if (it.key() == "orientation" && it.value() == findOrientation)
{
if (!TileDataJSON["floor"][idx]["image"].is_null())
{
std::cout << "Filename = " << TileDataJSON["floor"][idx]["image"].get<std::string>();
}
}
}
idx++;
}
It does work, but is there a better solution?
Here is a more elegant approach using std::find_if:
#include "json.hpp"
#include <iostream>
using json = nlohmann::json;
int main()
{
json j = R"([
{
"image": "floor_0.png",
"orientation": "flat"
},
{
"image": "floor_center.png",
"orientation": "center"
}
])"_json;
auto res = std::find_if(j.begin(), j.end(), [](const json& x) {
auto it = x.find("orientation");
return it != x.end() and it.value() == "center";
// alternative approach using value member function
// return x.is_object() and x.value("orientation", "") == "center";
});
std::cout << *res << std::endl;
}
Thank you! I llike that approach. Maybe you could add that to the documentation too?
Most helpful comment
Here is a more elegant approach using std::find_if: