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

Getting a flatten json to map<string, string> #1957

Closed
amirmasoudabdol opened this issue Feb 26, 2020 · 4 comments
Closed

Getting a flatten json to map<string, string> #1957

amirmasoudabdol opened this issue Feb 26, 2020 · 4 comments
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation

Comments

@amirmasoudabdol
Copy link
Contributor

I'm reading some on the flatten JSON, and I'm wondering what'd be the best way to cast the whole flatten json to a map<string, string>. I'm aware that I can iterate over items, and prepare it manually, but is there any better way?

I'm using C++17, and Apple Clang. I'm using the version 3.7.3.

@nlohmann
Copy link
Owner

Can you provide an example please?

@amirmasoudabdol
Copy link
Contributor Author

Now that I'm thinking about it, maybe it's not that straightforward, but this is what I'm trying to do:

    // create JSON value
     json j_flattened =
     {
         {"/answer/everything", 42},
         {"/happy", true},
         {"/list/0", 1},
         {"/list/1", 0},
         {"/list/2", 2},
         {"/name", "Niels"},
         {"/nothing", nullptr},
         {"/object/currency", "USD"},
         {"/object/value", 42.99},
         {"/pi", 3.141}
     };
  
     map<string, string> flatten_json_to_map;

So, I'd like to have the entire j_flattened into the flatten_json_to_map. I see that I need to do a lot of casting, but I'm thinking/asking whether there is an easier solution. I can use the fmt library but then I'll face the same problem of using std::to_string since I have to query the type of each value.

@nlohmann
Copy link
Owner

nlohmann commented Mar 5, 2020

No, there is no simple way. In particular, the library provides no built-in conversion from boolean/number/null/etc. to string. You could use dump() for these cases, but you would need to write your own function for this.

Idea (untested):

map<string, string> flatten_json_to_map(const json& j)
{
    map<string, string> result;

    auto flattened_j = j.flatten();

    for (auto entry : flattened_j.items())
    {
        switch (entry.value().type())
        {
            // avoid escaping string value
            case value_t::string:
                result[entry.key()] = entry.value();
                break;

            // use dump() for all other value types
            default:
                result[entry.key()] = entry.value().dump();
                break;
        }
    }

    return result;
}

@nlohmann nlohmann added the solution: proposed fix a fix for the issue has been proposed and waits for confirmation label Mar 5, 2020
@amirmasoudabdol
Copy link
Contributor Author

Your method indeed works and I don't see anything odd, yet. It's what I had in mind too. I'll close the issue and report if I found any bug in it.

Thanks! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind: question solution: proposed fix a fix for the issue has been proposed and waits for confirmation
Projects
None yet
Development

No branches or pull requests

2 participants