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

Storing multiple types inside map #831

Closed
lvkins opened this issue Nov 16, 2017 · 10 comments
Closed

Storing multiple types inside map #831

lvkins opened this issue Nov 16, 2017 · 10 comments

Comments

@lvkins
Copy link

lvkins commented Nov 16, 2017

Hello. Recently I have discovered this library and decided to give it a try. It looks really promising.

I have faced my first issue however. While performing JSON file loading I would like to parse and store some values by id in a map.

Like this:

m_loadedFile = json::parse(rdbuf);

// My map
enum jsonVar_t {
    UNIQUE_NUMBER,
    MESSAGE,
    INTERVAL,
};

std::map<jsonVar_t, json> test;

test.insert(std::make_pair(UNIQUE_NUMBER, m_loadedFile.at("uniqueNumber").get<int32_t>()));
test.insert(std::make_pair(MESSAGE, m_loadedFile.at("message").get<std::string>()));
test.insert(std::make_pair(INTERVAL, m_loadedFile.at("interval").get<float>()));

// Then I would like to access it like:

test[MESSAGE];

Basically it's working. However, when I'm printing test[MESSAGE] I get the message being quoted: "My Message". Similar issue for integers, which are not even integers (need to cast them in order).

How can I properly parse and store my data and then retrieve it with correct data type?

@gregmarr
Copy link
Contributor

gregmarr commented Nov 16, 2017

What does your JSON look like, and how are you printing test[MESSAGE]?

@lvkins
Copy link
Author

lvkins commented Nov 16, 2017

I'm putting it into the out stream std::cout << test[MESSAGE] << std::endl.

My JSON:

{
  "uniqueNumber": 1234,
  "message": "My Message",
  "interval": 19.24
}

@gregmarr
Copy link
Contributor

gregmarr commented Nov 16, 2017

It's most assuredly because your map contains json objects. So your m_loadedFile.at( code is pulling out a json object, using .get<>() to get a known type out of it, and then shoving it back into a json object in the map. You might be less confused about what's happening if you remove the .get<>() calls. You'll then see that you're just storing and printing out a dump() of a json object. In that dump(), strings are quoted.

If you want to store the primitive types in the map, you need to use a variant, or another struct that you create yourself that can store float, std::string, int32_t along with a type flag. Alternatively, you can leave it in the map as a json and extract the primitive from the json object when you go to use it.

@lvkins
Copy link
Author

lvkins commented Nov 16, 2017

Good point.

Alternatively, you can leave it in the map as a json and extract the primitive from the json object when you go to use it.

How do I manage to do that? What do you mean by extracting?

@gregmarr
Copy link
Contributor

How do I manage to do that? What do you mean by extracting?

Just like you did before:

test[UNIQUE_NUMBER].get<int32_t>();
test[MESSAGE].get<std::string>();
test[INTERVAL].get<float>();

@lvkins
Copy link
Author

lvkins commented Nov 16, 2017

Fine. There are two methods so far for extracting values:

  • at("name").get<T>();
  • value("name", "default");

Am I right?

I will post a solution here in case anyone would search for something like this.

@gregmarr
Copy link
Contributor

Yes, you can do value<T>() instead of at().get<T>() if you want to get a value from an object, with a default value if the name doesn't exist in the object. However, in your case, you don't have an object, you just have a primitive type, so you probably don't want to use that.

@nlohmann
Copy link
Owner

Any news on this @pompex ?

@lvkins
Copy link
Author

lvkins commented Nov 25, 2017

Oh yes, I just had to extract the values to wanted data type. Thats because objects stored in the map been still json objects.

So instead of mymap[KEY] I had to do mymap[KEY].value<T>().

@lvkins lvkins closed this as completed Nov 25, 2017
@nlohmann
Copy link
Owner

Thanks for reporting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants