You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于二级字段值对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。

解决方案

  1. 将JSON对象的所有键值对提取到std::vector中,载体元素类型为json::value_type(即std::pair<const std::string, json>);
  2. 对vector按照二级字段name的字符串值进行排序;
  3. 清空原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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 05:32:49