如何基于二级字段值对nlohmann JSON对象排序?解决迭代器报错
解决nlohmann::ordered_json按二级字段排序JSON对象的问题
问题场景
尝试用nlohmann::ordered_json对JSON对象按二级字段name排序,原代码如下:
#include <iostream> #include <algorithm> #include "json.hpp" using json = nlohmann::ordered_json; int main() { json j = R"({"321":{"name":"Bar"},"123":{"name":"Foo"}})"_json; std::cout << "Original:\n" << j << '\n'; std::sort(j.begin(), j.end(), [](const json a, const json b) { return a["name"].get<std::string>().compare(b["name"].get<std::string>()) < 0; }); std::cout << "Sorted:\n" << j << '\n'; return 0; }
运行时抛出异常:
terminate called after throwing an instance of 'nlohmann::json_abi_v3_11_2::detail::invalid_iterator' what(): [json.exception.invalid_iterator.209] cannot use offsets with object iterators
需求是将JSON对象按二级name字段排序,得到预期输出:
Original: {"123":{"name":"Foo"},"321":{"name":"Bar"}} Sorted: {"321":{"name":"Bar"},"123":{"name":"Foo"}}
错误原因
std::sort要求迭代器支持随机访问,但nlohmann::ordered_json对象的迭代器是键值对迭代器,不支持随机访问;同时JSON对象是键值对映射结构,不能像数组那样直接对元素范围调用std::sort。
解决方案
- 将JSON对象的所有键值对提取到
std::vector中,载体元素类型为json::value_type(即std::pair<const std::string, json>); - 对vector按照二级字段
name的字符串值进行排序; - 清空原JSON对象,将排序后的键值对依次插入,利用
ordered_json保留插入顺序的特性得到排序结果。
修正后的完整代码
#include <iostream> #include <algorithm> #include <vector> #include "json.hpp" using json = nlohmann::ordered_json; int main() { json j = R"({"321":{"name":"Bar"},"123":{"name":"Foo"}})"_json; std::cout << "Original:\n" << j << '\n'; // 提取所有键值对到vector std::vector<json::value_type> kv_pairs(j.begin(), j.end()); // 按二级name字段的字符串值升序排序 std::sort(kv_pairs.begin(), kv_pairs.end(), [](const json::value_type& a, const json::value_type& b) { return a.second["name"].get<std::string>() < b.second["name"].get<std::string>(); }); // 重建排序后的ordered_json对象 j.clear(); for (const auto& pair : kv_pairs) { j[pair.first] = pair.second; } std::cout << "Sorted:\n" << j << '\n'; return 0; }
预期输出
Original: {"123":{"name":"Foo"},"321":{"name":"Bar"}} Sorted: {"321":{"name":"Bar"},"123":{"name":"Foo"}}
内容的提问来源于stack exchange,提问作者dtrunk
相关产品推荐
相关产品推荐

