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

How to determine the type of elements read from a JSON array? #1564

Closed
amwink opened this issue Apr 11, 2019 · 5 comments
Closed

How to determine the type of elements read from a JSON array? #1564

amwink opened this issue Apr 11, 2019 · 5 comments

Comments

@amwink
Copy link

amwink commented Apr 11, 2019

The JSON files I need to read with my program have the form
{ "labels": [ 0, 0, 1, 1 ], "vectors": [ [ 1, 1 ], [ 2, 2 ], [ 2, 4 ], [ 4, 2 ] ] }
or
{ "labels": [ 0, 0, 1, 1 ], "vectors": [ "file1", "file2", "file3", "file4" ] }
to represent specimen that have a numerical label and numerical data, the second of which may be given in the JSONs themselves or read from files.

The labels are read in the line

std::vector <float> *y = 
     new std::vector <float> ( jdesign["labels"].get<std::vector<float>>() );

and for the first form the line

std::vector<std::vector<float>> 
     xtest1 ( jdesign["vectors"].get<std::vector<std::vector<intensity>>>() );

does the trick. But if I want to test for the second form (the values are given as file names) and use

std::vector<std::string> 
     xtest2 ( jdesign["vectors"].get<std::vector<std::string>>() );

I get:

terminate called after throwing an instance of 'nlohmann::detail::type_error'
what():  [json.exception.type_error.302] type must be string, but is array`

Is there a way to find out the type of the elements of vectors before assigning them to my program variables?

I am using Debian Linux (stretch, kernel 4.9.0-8-amd64) and GCC 8.2.0 and the json library as pulled from the GitHub repository.

@nlohmann
Copy link
Owner

You could call type() to get the type.

@amwink
Copy link
Author

amwink commented Apr 12, 2019

Thanks! but both examples above are json::value_t::array -- is it possible to test the types of the array elements in some way?

@nlohmann
Copy link
Owner

You would need to call it for each element. As the array has a begin/end iterator, you can also use std::all_of together with functions like is_string to check if all elements are strings, for example.

@amwink
Copy link
Author

amwink commented Apr 12, 2019

That makes sense, thanks again. But if I understand it correctly then I would always first need to do a get<T>() before I could check the contents of the array, which sounds like a catch-22? I think it is better then to add a variable to the JSON to find out what T should be before calling get<T>().

@amwink amwink closed this as completed Apr 12, 2019
@nlohmann
Copy link
Owner

No, you can access the JSON vector before this:

if (std::all_of(jdesign["vectors"].begin(), jdesign["vectors"].end(), [](const json& el){ return el.is_string(); })
{
   // access as string vector, e.g. like
   std::vector<std::string> foo = jdesign["vectors"];
}

(untested code, but you should get the gist).

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

No branches or pull requests

2 participants