✨ add recursive update function for iterator range
This commit is contained in:
parent
685327f48e
commit
9fba12704d
@ -7,12 +7,17 @@ using json = nlohmann::json;
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
// create two JSON objects
|
// create two JSON objects
|
||||||
json o1 = R"( {"color": "red", "price": 17.99} )"_json;
|
json o1 = R"( {"color": "red", "price": 17.99, "names": {"de": "Flugzeug"}} )"_json;
|
||||||
json o2 = R"( {"color": "blue", "speed": 100} )"_json;
|
json o2 = R"( {"color": "blue", "speed": 100, "names": {"en": "plane"}} )"_json;
|
||||||
|
json o3 = o1;
|
||||||
|
|
||||||
// add all keys from o2 to o1 (updating "color")
|
// add all keys from o2 to o1 (updating "color", replacing "names")
|
||||||
o1.update(o2.begin(), o2.end());
|
o1.update(o2.begin(), o2.end());
|
||||||
|
|
||||||
// output updated object o1
|
// add all keys from o2 to o1 (updating "color", merging "names")
|
||||||
|
o3.update(o2.begin(), o2.end(), true);
|
||||||
|
|
||||||
|
// output updated object o1 and o3
|
||||||
std::cout << std::setw(2) << o1 << '\n';
|
std::cout << std::setw(2) << o1 << '\n';
|
||||||
|
std::cout << std::setw(2) << o3 << '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,17 @@
|
|||||||
{
|
{
|
||||||
"color": "blue",
|
"color": "blue",
|
||||||
|
"names": {
|
||||||
|
"en": "plane"
|
||||||
|
},
|
||||||
|
"price": 17.99,
|
||||||
|
"speed": 100
|
||||||
|
}
|
||||||
|
{
|
||||||
|
"color": "blue",
|
||||||
|
"names": {
|
||||||
|
"de": "Flugzeug",
|
||||||
|
"en": "plane"
|
||||||
|
},
|
||||||
"price": 17.99,
|
"price": 17.99,
|
||||||
"speed": 100
|
"speed": 100
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,12 +5,14 @@
|
|||||||
void update(const_reference j, bool merge_objects = false);
|
void update(const_reference j, bool merge_objects = false);
|
||||||
|
|
||||||
// (2)
|
// (2)
|
||||||
void update(const_iterator first, const_iterator last);
|
void update(const_iterator first, const_iterator last, bool merge_objects = false);
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Inserts all values from JSON object `j`. and overwrites existing keys. When `merge_objects` is `#!c false` (default),
|
1. Inserts all values from JSON object `j`.
|
||||||
existing keys are overwritten. When `merge_objects` is `#!c true`, recursively merges objects with common keys.
|
2. Inserts all values from from range `[first, last)`
|
||||||
2. Inserts all values from from range `[first, last)` and overwrites existing keys.
|
|
||||||
|
When `merge_objects` is `#!c false` (default), existing keys are overwritten. When `merge_objects` is `#!c true`,
|
||||||
|
recursively merges objects with common keys.
|
||||||
|
|
||||||
The function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update)
|
The function is motivated by Python's [dict.update](https://docs.python.org/3.6/library/stdtypes.html#dict.update)
|
||||||
function.
|
function.
|
||||||
|
|||||||
@ -6002,39 +6002,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
*/
|
*/
|
||||||
void update(const_reference j, bool merge_objects = false)
|
void update(const_reference j, bool merge_objects = false)
|
||||||
{
|
{
|
||||||
// implicitly convert null value to an empty object
|
update(j.begin(), j.end(), merge_objects);
|
||||||
if (is_null())
|
|
||||||
{
|
|
||||||
m_type = value_t::object;
|
|
||||||
m_value.object = create<object_t>();
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
|
|
||||||
}
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = j.cbegin(); it != j.cend(); ++it)
|
|
||||||
{
|
|
||||||
if (merge_objects && it.value().is_object())
|
|
||||||
{
|
|
||||||
auto it2 = m_value.object->find(it.key());
|
|
||||||
if (it2 != m_value.object->end())
|
|
||||||
{
|
|
||||||
it2->second.update(it.value(), true);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_value.object->operator[](it.key()) = it.value();
|
|
||||||
#if JSON_DIAGNOSTICS
|
|
||||||
m_value.object->operator[](it.key()).m_parent = this;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -6045,6 +6013,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@param[in] first begin of the range of elements to insert
|
@param[in] first begin of the range of elements to insert
|
||||||
@param[in] last end of the range of elements to insert
|
@param[in] last end of the range of elements to insert
|
||||||
|
@param[in] merge_objects when true, existing keys are not overwritten, but
|
||||||
|
contents of objects are merged recursively
|
||||||
|
(default: false)
|
||||||
|
|
||||||
@throw type_error.312 if called on JSON values other than objects; example:
|
@throw type_error.312 if called on JSON values other than objects; example:
|
||||||
`"cannot use update() with string"`
|
`"cannot use update() with string"`
|
||||||
@ -6061,9 +6032,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0, `merge_objects` parameter added in 3.10.4.
|
||||||
*/
|
*/
|
||||||
void update(const_iterator first, const_iterator last)
|
void update(const_iterator first, const_iterator last, bool merge_objects = false)
|
||||||
{
|
{
|
||||||
// implicitly convert null value to an empty object
|
// implicitly convert null value to an empty object
|
||||||
if (is_null())
|
if (is_null())
|
||||||
@ -6093,6 +6064,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
for (auto it = first; it != last; ++it)
|
for (auto it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
|
if (merge_objects && it.value().is_object())
|
||||||
|
{
|
||||||
|
auto it2 = m_value.object->find(it.key());
|
||||||
|
if (it2 != m_value.object->end())
|
||||||
|
{
|
||||||
|
it2->second.update(it.value(), true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_value.object->operator[](it.key()) = it.value();
|
m_value.object->operator[](it.key()) = it.value();
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
m_value.object->operator[](it.key()).m_parent = this;
|
m_value.object->operator[](it.key()).m_parent = this;
|
||||||
|
|||||||
@ -23471,6 +23471,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
Inserts all values from JSON object @a j and overwrites existing keys.
|
Inserts all values from JSON object @a j and overwrites existing keys.
|
||||||
|
|
||||||
@param[in] j JSON object to read values from
|
@param[in] j JSON object to read values from
|
||||||
|
@param[in] merge_objects when true, existing keys are not overwritten, but
|
||||||
|
contents of objects are merged recursively
|
||||||
|
(default: false)
|
||||||
|
|
||||||
@throw type_error.312 if called on JSON values other than objects; example:
|
@throw type_error.312 if called on JSON values other than objects; example:
|
||||||
`"cannot use update() with string"`
|
`"cannot use update() with string"`
|
||||||
@ -23482,43 +23485,11 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0, `merge_objects` parameter added in 3.10.4.
|
||||||
*/
|
*/
|
||||||
void update(const_reference j, bool recursive = false)
|
void update(const_reference j, bool merge_objects = false)
|
||||||
{
|
{
|
||||||
// implicitly convert null value to an empty object
|
update(j.begin(), j.end(), merge_objects);
|
||||||
if (is_null())
|
|
||||||
{
|
|
||||||
m_type = value_t::object;
|
|
||||||
m_value.object = create<object_t>();
|
|
||||||
assert_invariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!is_object()))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(type_name()), *this));
|
|
||||||
}
|
|
||||||
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
|
|
||||||
{
|
|
||||||
JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name()), *this));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto it = j.cbegin(); it != j.cend(); ++it)
|
|
||||||
{
|
|
||||||
if (recursive && it.value().is_object())
|
|
||||||
{
|
|
||||||
auto it2 = m_value.object->find(it.key());
|
|
||||||
if (it2 != m_value.object->end())
|
|
||||||
{
|
|
||||||
it2->second.update(it.value(), recursive);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_value.object->operator[](it.key()) = it.value();
|
|
||||||
#if JSON_DIAGNOSTICS
|
|
||||||
m_value.object->operator[](it.key()).m_parent = this;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -23529,6 +23500,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@param[in] first begin of the range of elements to insert
|
@param[in] first begin of the range of elements to insert
|
||||||
@param[in] last end of the range of elements to insert
|
@param[in] last end of the range of elements to insert
|
||||||
|
@param[in] merge_objects when true, existing keys are not overwritten, but
|
||||||
|
contents of objects are merged recursively
|
||||||
|
(default: false)
|
||||||
|
|
||||||
@throw type_error.312 if called on JSON values other than objects; example:
|
@throw type_error.312 if called on JSON values other than objects; example:
|
||||||
`"cannot use update() with string"`
|
`"cannot use update() with string"`
|
||||||
@ -23545,9 +23519,9 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
@sa https://docs.python.org/3.6/library/stdtypes.html#dict.update
|
||||||
|
|
||||||
@since version 3.0.0
|
@since version 3.0.0, `merge_objects` parameter added in 3.10.4.
|
||||||
*/
|
*/
|
||||||
void update(const_iterator first, const_iterator last)
|
void update(const_iterator first, const_iterator last, bool merge_objects = false)
|
||||||
{
|
{
|
||||||
// implicitly convert null value to an empty object
|
// implicitly convert null value to an empty object
|
||||||
if (is_null())
|
if (is_null())
|
||||||
@ -23577,6 +23551,15 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
|
|
||||||
for (auto it = first; it != last; ++it)
|
for (auto it = first; it != last; ++it)
|
||||||
{
|
{
|
||||||
|
if (merge_objects && it.value().is_object())
|
||||||
|
{
|
||||||
|
auto it2 = m_value.object->find(it.key());
|
||||||
|
if (it2 != m_value.object->end())
|
||||||
|
{
|
||||||
|
it2->second.update(it.value(), true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
m_value.object->operator[](it.key()) = it.value();
|
m_value.object->operator[](it.key()) = it.value();
|
||||||
#if JSON_DIAGNOSTICS
|
#if JSON_DIAGNOSTICS
|
||||||
m_value.object->operator[](it.key()).m_parent = this;
|
m_value.object->operator[](it.key()).m_parent = this;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user