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

Efficient way to set a json object as value into another json key #1406

Closed
ibc opened this issue Dec 24, 2018 · 5 comments
Closed

Efficient way to set a json object as value into another json key #1406

ibc opened this issue Dec 24, 2018 · 5 comments

Comments

@ibc
Copy link

ibc commented Dec 24, 2018

I've a function somewhere that creates and returns a json data object, and I want to use such a json data as value into the "data" key of another json response object.

Currently I'm doing something like this, and just wonder whether there is a way to avoid the data copy:

json response = json::object();

response["id"] = this->id;
response["data"] = this->foo.GetJsonData(); // This produces a `json`.

this->DoSomethingWith(response);

I expect there is no magic here and the json data returned by foo.GetJsonData() is being mem copied into response["data"]. May be I should, instead, do something like this?:

json response = json::object();

response["id"] = this->id;

// Allocate empty object for "data" key:
response["data"] = json::object();

// Get iterator to "data" object:
auto dataIterator = response.find("data"); 

// Pass the iterator to `foo.GetJsonData()` so it adds its keys/values into it.
this->foo.GetJsonData(dataIterator);

this->DoSomethingWith(response);

Then, void Foo::GetJsonData(json::iterator dataIterator) would do something like:

(*dataIterator)["foo"] = "FOO";
(*dataIterator)["bar"] = 1234;

Does it make any sense?

@gregmarr
Copy link
Contributor

Yes, this would definitely be more efficient:

void Foo::GetJsonData(json &storeDataInHere) {
    storeDataInHere["foo"] = "FOO";
    storeDataInHere["bar"] = 1234;
}

this->foo.GetJsonData(response["data"]);

@ibc
Copy link
Author

ibc commented Dec 27, 2018

Already using it, thanks :)

@ibc ibc closed this as completed Dec 27, 2018
@ibc
Copy link
Author

ibc commented Dec 27, 2018

Sorry, just a question: Is there any way to optimize this?:

// Allocate empty object for "data" key:
response["data"] = json::object();

// Get iterator to "data" object:
auto dataIterator = response.find("data"); 

Obviously the response.find("data") is internally checking whether "data" exists in the map and so on. Is there something as follows?:

// Allocate empty object for "data" key and get its iterator:
auto dataIterator = response.addKeyValue("data", json::object());

...where addKeyValue() is a method that receives a key and value and returns a iterator to the new created value.

Obviously it does not exist, just wondering if it makes sense :)

@gregmarr
Copy link
Contributor

Read what I posted above again, and I think you'll find your answer. Maybe this will help:

json response = json::object();
response["id"] = this->id;
this->foo.GetJsonData(response["data"]);

@ibc
Copy link
Author

ibc commented Dec 27, 2018

Ok, so you are directly passing response["data"] to foo.GetJsonData(), this is, you are creating a "data" key in-place, great!

I have to remove some asserts that check storeDataInHere.is_object() to make it work, but nothing else. Thanks!

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

2 participants