-
-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
Using STL algorithms with JSON containers with expected results? #1045
Comments
Indeed, the It should expose the 5 typedefs needed by |
The iteration wrapper was originally designed to be used in a range |
I gave this issue a first try (see commit 8d8f890), but got stuck with this error message
|
I think the issue's root comes from the fact that Thus json does not model the Container concept on that point, since I would rather go for a different iterator that should be created explicitly by users: for (const auto& key_value : nlohmann::whatever_iterator{j}) {
key_value.key();
} IIRC that was |
|
I am stuck here. Any ideas? |
Couldn't What is the rationale behind |
To be honest: the code in |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Hi @nlohmann , template<typename IteratorType> class iteration_proxy; // TODO: Forward decl needed, maybe move it somewhere else
template<typename BasicJsonType, typename T,
enable_if_t<std::is_same<T, typename iteration_proxy<typename BasicJsonType::iterator>::iteration_proxy_internal>::value, int> = 0>
void to_json(BasicJsonType& j, T b) noexcept
{
typename BasicJsonType::object_t tmp_obj;
tmp_obj[b.key()] = b.value(); // TODO: maybe there is a better way?
external_constructor<value_t::object>::construct(j, std::move(tmp_obj));
} side note: need to make iteration_proxy_internal a friend of to_json (or make it public). SECTION("issue #1045 - Using STL algorithms with JSON containers with expected results?")
{
json diffs = nlohmann::json::array();
json m1{{"key1", 42}};
json m2{{"key2", 42}};
auto p1 = m1.items();
auto p2 = m2.items();
using it_type = decltype(p1.begin());
std::set_difference(
p1.begin(), p1.end(),
p2.begin(), p2.end(),
std::inserter(diffs, diffs.end()), [&](const it_type & e1, const it_type & e2) -> bool
{
using comper_pair = std::pair<std::string, decltype(e1.value())>; // Trying to avoid unneeded copy
return comper_pair(e1.key(), e1.value()) < comper_pair(e2.key(), e2.value()); // Using pair comper
});
CHECK(diffs.size() == 1); // Note the change here, was 2
} Sadly I don't have time to make it as a pull-request, but I hope it helps. |
…nternal was needed
Fixed with #1134. |
I'd like to use JSON as any other STL container with the same expected results. For example, given this code snippet:
the output is:
which is not what I expected. I'd really want to be able to compare JSON containers, including their keys.
The reason is that JSON iterators, when dereferenced, only return a reference to the value pointed to by the iterator (compare with std::map returning a std::pair of its key&value).
But then I thought I could use the proxy iterator: iteration_proxy and its key and value methods to work around my problem by writing a custom comparator and use it with std::set_difference:
This however, fails to compile. The compiler (g++ 7.2 (on Ubuntu 16.04)) complains that there is no iterator_category or value_type in iteration_proxy_internal. Hmm. From its name, and from the compiler message, I guess the iterator proxy is not an iterator. But, could it easily be extended to support my use case? Or can I solve my problem in another way? Or do I have to resort to writing my own algorithms for the JSON containers?
The text was updated successfully, but these errors were encountered: