Files
json/docs/mkdocs/docs/features/iterators.md
Niels Lohmann 6a7392058e Complete documentation for 3.11.0 (#3464)
* 👥 update contributor and sponsor list

* 🚧 document BJData format

* 🚧 document BJData format

* 📝 clarified documentation of [json.exception.parse_error.112]

* ✏️ adjust titles

* 📝 add more examples

* 🚨 adjust warnings for index.md files

* 📝 add more examples

* 🔥 remove example for deprecated code

* 📝 add missing enum entry

* 📝 overwork table for binary formats

*  add test to create table for binary formats

* 📝 fix wording in example

* 📝 add more examples

* Update iterators.md (#3481)

*  add check for overloads to linter #3455

* 👥 update contributor list

* 📝 add more examples

* 📝 fix documentation

* 📝 add more examples

* 🎨 fix indentation

* 🔥 remove example for destructor

* 📝 overwork documentation

* Updated BJData documentation, #3464 (#3493)

* update bjdata.md for #3464

* Minor edit

* Fix URL typo

* Add info on demoting ND array to a 1-D optimized array when singleton dimension

Co-authored-by: Chaoqi Zhang <prncoprs@163.com>
Co-authored-by: Qianqian Fang <fangqq@gmail.com>
2022-05-17 13:08:56 +02:00

4.0 KiB

Iterators

Overview

A basic_json value is a container and allows access via iterators. Depending on the value type, basic_json stores zero or more values.

As for other containers, begin() returns an iterator to the first value and end() returns an iterator to the value following the last value. The latter iterator is a placeholder and cannot be dereferenced. In case of null values, empty arrays, or empty objects, begin() will return end().

Illustration from cppreference.com

Iteration order for objects

When iterating over objects, values are ordered with respect to the object_comparator_t type which defaults to std::less. See the types documentation for more information.

??? example

```cpp
// create JSON object {"one": 1, "two": 2, "three": 3}
json j;
j["one"] = 1;
j["two"] = 2;
j["three"] = 3;

for (auto it = j.begin(); it != j.end(); ++it)
{
    std::cout << *it << std::endl;
}
```

Output:

```json
1
3
2
```

The reason for the order is the lexicographic ordering of the object keys "one", "three", "two".

Access object key during iteration

The JSON iterators have two member functions, key() and value() to access the object key and stored value, respectively. When calling key() on a non-object iterator, an invalid_iterator.207 exception is thrown.

??? example

```cpp
// create JSON object {"one": 1, "two": 2, "three": 3}
json j;
j["one"] = 1;
j["two"] = 2;
j["three"] = 3;

for (auto it = j.begin(); it != j.end(); ++it)
{
    std::cout << it.key() << " : " << it.value() << std::endl;
}
```

Output:

```json
one : 1
three : 3
two : 2
```

Range-based for loops

C++11 allows using range-based for loops to iterate over a container.

for (auto it : j_object)
{
    // "it" is of type json::reference and has no key() member
    std::cout << "value: " << it << '\n';
}

For this reason, the items() function allows accessing iterator::key() and iterator::value() during range-based for loops. In these loops, a reference to the JSON values is returned, so there is no access to the underlying iterator.

for (auto& el : j_object.items())
{
    std::cout << "key: " << el.key() << ", value:" << el.value() << '\n';
}

The items() function also allows using structured bindings (C++17):

for (auto& [key, val] : j_object.items())
{
    std::cout << "key: " << key << ", value:" << val << '\n';
}

!!! note

When iterating over an array, `key()` will return the index of the element as string. For primitive types (e.g., numbers), `key()` returns an empty string.

!!! warning

Using `items()` on temporary objects is dangerous. Make sure the object's lifetime exceeds the iteration. See <https://github.com/nlohmann/json/issues/2040> for more information.

Reverse iteration order

rbegin() and rend() return iterators in the reverse sequence.

Illustration from cppreference.com

??? example

```cpp
json j = {1, 2, 3, 4};

for (auto it = j.rbegin(); it != j.rend(); ++it)
{
    std::cout << *it << std::endl;
}
```

Output:

```json
4
3
2
1
```

Iterating strings and binary values

Note that "value" means a JSON value in this setting, not values stored in the underlying containers. That is, *begin() returns the complete string or binary array and is also safe the underlying string or binary array is empty.

??? example

```cpp
json j = "Hello, world";
for (auto it = j.begin(); it != j.end(); ++it)
{
    std::cout << *it << std::endl;
}
```

Output:

```json
"Hello, world"
```

Iterator invalidation

Operations invalidated iterators
clear all