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

Retrieving array elements. #1369

Closed
kepler425b opened this issue Nov 22, 2018 · 6 comments
Closed

Retrieving array elements. #1369

kepler425b opened this issue Nov 22, 2018 · 6 comments
Labels
state: needs more info the author of the issue needs to provide more details

Comments

@kepler425b
Copy link

kepler425b commented Nov 22, 2018

data is a json document, "nodes" is an array containing arrays in the document.
The confusion I have with this library is when I get returned an object type iterator and when array type iterator. For example using a "find" function as in this line: json::iterator c = data.find("nodes"); I expect to retrieve direct iterator for that array, but I get returned an object type.
image

How would you iterate the "nodes" array and access elements of it?
This loop throws exception but I'll just paste it here to get an idea of what I am trying to achieve:

json::iterator c = data.find("nodes");

			if (c.key() == "nodes")
			{
				for (json::iterator ak = c->begin(); c != c->end(); ak++)
				{
					if (ak[0].is_number_float() && ak[1].is_number_float() && ak[2].is_number_float() && ak[3].is_number_float())
					{
                                        } 
                                }
                        }

While in rapidjson I do it this way:

Value::ConstMemberIterator c = itr->value.FindMember("nodes");

			if (c != data.MemberEnd() && c->name == "nodes")
			{
				for (Value::ConstValueIterator b = c->value.Begin(); b != c->value.End(); b++)
				{
					if (b->IsArray())
					{
						for (Value::ConstValueIterator j = b->Begin(); j != b->End(); j++)
						if (j[0].IsString() && j[1].IsFloat() && j[2].IsFloat() && j[3].IsFloat())
						{
                                                }
                                         }
                                }
                         }

and it's quite intuitive what it does, you get and iterator and it holds a value to whatever it has, you use that pointer to retrieve elements. If it's array type, you just use [] operator to index into elements.
I read the docs of nlohmann library many times, looked through examples but I didn't find them useful.

@nlohmann
Copy link
Owner

How does the JSON value in data looks like?

@kepler425b
Copy link
Author

kepler425b commented Nov 22, 2018

How does the JSON value in data looks like?

What do you mean? The json file? https://i.imgur.com/v4kdPeF.png

@nlohmann
Copy link
Owner

Can you paste it here? I cannot parse images :-)

@kepler425b
Copy link
Author

kepler425b commented Nov 22, 2018

Can you paste it here? I cannot parse images :-)

{
	"Cube":{
		"information":{
			"name":"",
			"authors":""},
		"slotType":"main",
//--Nodes--
		"nodes":[
			["id", "posX", "posY", "posZ"],
			["nl0",0.26,-0.26,-0.26],
			["nl1",0.26,-0.26,0.26],
			["nr2",-0.26,-0.26,-0.26],
			["nr3",-0.26,-0.26,0.26],
			["nl4",0.26,0.26,-0.26],
			],
//--Beams--
		"beams":[
			["id1:", "id2:"],
			["nl1","nl0"],
			["nl0","nl4"],
			["nl5","nl4"],
			["nr7","nl5"],
	

			],
//--tri col--
		"triangles":[
			["id1:", "id2:", "id3:"],
			["nr3","nr6","nr2"],
			["nr7","nl4","nr6"],
			["nr7","nr3","nl1"],
			],
	}
}

@pratikpc
Copy link
Contributor

pratikpc commented Dec 9, 2018

@kepler425b the Json String posted by you was a bit incorrect, at least according to https://jsonlint.com/
The Corrected Json is.

{
	"Cube": {
		"information": {
			"name": "",
			"authors": ""
		},
		"slotType": "main",
		"nodes": [
			["id", "posX", "posY", "posZ"],
			["nl0", 0.26, -0.26, -0.26],
			["nl1", 0.26, -0.26, 0.26],
			["nr2", -0.26, -0.26, -0.26],
			["nr3", -0.26, -0.26, 0.26],
			["nl4", 0.26, 0.26, -0.26]
		],
		"beams": [
			["id1:", "id2:"],
			["nl1", "nl0"],
			["nl0", "nl4"],
			["nl5", "nl4"],
			["nr7", "nl5"]


		],
		"triangles": [
			["id1:", "id2:", "id3:"],
			["nr3", "nr6", "nr2"],
			["nr7", "nl4", "nr6"],
			["nr7", "nr3", "nl1"]
		]
	}
}

Note the hierarchy involved in the Json here
At the top you have Cubes.
And then you have Nodes which is a child of Cubes.

As such what your code should consist of doing is first performing a find on the Cube and verify if it exists.
And then search for Node within the returned type
And then iterating over it.

Note that just like Regular Find implemented by STL and also by RapidJson, Nlohmann's Json returns end() when find fails

To give you an idea, check out the code here

   auto const cube = json.find("Cube");
   // Verify if Cube exists
   // Returns json.end if it doesn't
   if (cube == json.end())
   {
      std::cerr << "Cube Not Found";
      return 1;
   }
   auto const nodes = cube->find("nodes");
   // Verify if Nodes exists
   // Returns cube->end if it doesnt
   if (nodes == cube->end())
   {
      std::cerr << "Node Not Found";
      return 1;
   }

A small mistake you performed was that you decided to search directly for nodes within the main Json rather than follow the hierarchy of cube -> nodes

Now coming to your loop, I am not sure if it's correct or incorrect...
But usually in C++11 you should use Range Based For Loops

for (auto const& node : *nodes)
{
// Your Code here
}

This obviously has the benefit of looking simpler and being simpler to use.

Notice that your if statement has a minor issue as well.
You are checking if the first element is Float or not.
But in the Sample provided, none of the First Elements are Floating-Points.
They are always Strings.
So the if condition would never be true.

If you are still confused, feel free to ask

@nlohmann
Copy link
Owner

@kepler425b Did @pratikpc 's answer help you?

@nlohmann nlohmann added the state: needs more info the author of the issue needs to provide more details label Dec 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: needs more info the author of the issue needs to provide more details
Projects
None yet
Development

No branches or pull requests

3 participants