How to modify a json object using json11 library?

I have a already json11 object build:

Json my_json = Json::object { { "key1", "value1" }, { "key2", false }, { "key3", Json::array { 1, 2, 3 } }, }; 

And I want to add a new value to key3 array like this:

my_json["keys3"].push_back(4); 

How I can achieve that? I can't see anything to modify objects (all operator to access values are const!)

3 Answers

Unfortunately it seems you cannot modify directly an instance of Json.
It's an opaque wrapper around a JsonValue that is inaccessible.

Anyway, note that a Json::object is a std::map<std::string, Json>. You can create a copy of your original Json::object as it follows:

Json::object json_obj = my_json.object_items(); 

Then the key keys3 contains a Json::array, that is nothing more than a std::vector<Json>.
You can modify it as it follows:

json_obj["keys3"].push_back(4); 

Finally you must create a new Json from your Json::object and that's all:

Json another_json = json_obj; 

Quite expensive an operation.
I suspect the right way is to create your objects step by step and at the very end of your process create an instance of a Json.

1

I found next issues on github about this question:

  • [: more o less the same that skypjack explain

The Json type is immutable, but the Json::object type is just a std::map, so your code would work if the first line created a Json::object instead. You can use that map to build whatever data you want, then wrap it in as Json(data) when you're done modifying it. You can also extract the map from a Json using object_items(), copy it, mutate it, and use it to create a new Json, similar to a builder pattern.

  • [: This one is very interesting because explain why it's not possible to modify a json

The Json type is intended to be an immutable value type, which has a number of advantages including thread safety and the ability to share data across copies. If you want a mutable array you can use a Json::array (which is just a typedef for a vector) and mutate it freely before putting it into a Json object.

If you are using json11 you can do it like this:

Json json = Json::object { { "num_neurons_in_each_layer", Json::array{ 1000, 1000, 10, 10 } }, { "non_editable_data", Json::object { {"train_error", -1.0 }, {"validation_error", -1.0 } } } }; Json* p_error = const_cast<Json*>(&json["non_editable_data"]. object_items().find("validation_error")->second); *p_error = Json(2.0); //"validation_error" has been modified to 2.0 p_error = nullptr; delete p_error; 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like