4.9 KiB
Element Access
There are many ways elements in a JSON value can be accessed:
- unchecked access via
operator[] - checked access via
at - access with default value via
value - iterators
- JSON pointers
Testing whether a key or index exists before accessing it is also possible, with contains or find (which returns an iterator to the value, or end() if it is not found).
How do I get a value out? Start at the top and follow the first question that applies:
flowchart TD
A["getting a value out"] --> P{{"nested path such as /server/port?"}}
P -->|"yes"| JP["JSON Pointer: at(ptr), value(ptr, default), contains(ptr)"]
P -->|"no, one key or index"| T{{"only testing whether it exists?"}}
T -->|"yes"| CF["contains() / find()"]
T -->|"no"| M{{"may it be missing?"}}
M -->|"yes, a fallback is fine"| V["value(key, default)"]
M -->|"yes, and missing is an error"| AT["at(): throws out_of_range"]
M -->|"no, it exists and its type is known"| OP["operator[] and get#lt;T#gt;()"]
OP -.- W["non-const operator[] inserts null for a missing key"]
Decision tree for reading a value: the labels on the arrows are the answers to the questions, and the boxes name the functions to use. The dashed line marks a side effect of the non-const operator[].
Does this key exist?
Use contains to test for a key; it does not modify the value and does not throw:
json j = {{"name", "Mary"}, {"address", {{"city", "Berlin"}}}};
j.contains("name"); // true
j.contains("age"); // false
j.contains("city"); // false: contains() only looks at the top level
j["address"].contains("city"); // true
j.contains(json::json_pointer("/address/city")); // true: a JSON pointer tests a nested path in one call
If the value is needed afterwards, find tests and accesses with a single lookup:
if (auto it = j.find("name"); it != j.end())
{
std::cout << *it << '\n';
}
contains also returns true for a key whose value is null; use j.contains("k") && !j["k"].is_null() if a null should count as missing. To read a value with a fallback instead, see value.
operator[] inserts missing keys
Like std::map::operator[], the non-const operator[] adds a null value if the key is missing. Testing a key with it therefore changes the object:
json j = {{"foo", 1}};
bool absent = j["bar"].is_null(); // true, but j is now {"bar": null, "foo": 1}
Use contains/find to test, and at to access a value that must exist (it throws an out_of_range exception otherwise).
See also
operator[]- unchecked accessat- checked accessvalue- access with default valuecontains- andfind- test for existencefront- andback- first and last elementitems- iterate over keys and values- Checked access: at - access with range checking
- Unchecked access: operator[] - access without range checking
- Access with default value: value - fall back to a default instead of throwing
- Iterators - visit all elements of arrays and objects
- JSON Pointer - address nested values with a single string
- Modifying values - add, merge and remove elements
basic_json- all member functions