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

如何在Rust中过滤多维数组?基于Serde的JSON数据筛选问题

问题

我有如下JSON数据,需要用Rust结合Serde库解析。目前能通过以下代码访问部分内容:

let v: serde_json::Value = serde_json::from_str(&data).expect("Unable to parse");
let sessions = v["data"]["sessions"].as_array().unwrap();
let programs = v["data"]["programs"].as_array().unwrap();

但我想通过programs.id的值筛选出对应的programData数组项,尝试了下面的代码却编译报错,提示‘no implementation’:

for x in programs {
        let programId = &x["id"];

        // 无法运行——编译时出现‘no implementation’错误
        let programSessions = sessions.iter().filter(|&f| f["programData"].as_array().unwrap()["programRefId"] == programId).collect();
    }

对应的JSON数据:

{
  "data": {
    "name": "my name",
    "sessions": [
      {
        "id": 1,
        "programData": [
          {
            "dataPhase": 1,
            "programRefId": 2,
            "programSpecificData": {
              "completed": false
            }
          },
          {
            "dataPhase": 2,
            "programRefId": 3,
            "programSpecificData": {
              "completed": true
            }
          }
        ]
      }
    ],
    "programs": [
      {
        "id": 3
      }
    ]
  }
}

解决方案

你的代码存在两个核心问题:

  1. 数组访问逻辑错误:f["programData"].as_array().unwrap()得到的是数组类型,直接用["programRefId"]索引数组是无效操作——数组需要遍历内部元素才能获取每个元素的programRefId。
  2. 类型推断与比较问题:serde_json::Value的比较需要保证类型完全一致,且collect()未指定目标类型,Rust无法自动推断。

修复后的完整代码如下:

use serde_json::Value;

fn main() {
    let data = r#"{
  "data": {
    "name": "my name",
    "sessions": [
      {
        "id": 1,
        "programData": [
          {
            "dataPhase": 1,
            "programRefId": 2,
            "programSpecificData": {
              "completed": false
            }
          },
          {
            "dataPhase": 2,
            "programRefId": 3,
            "programSpecificData": {
              "completed": true
            }
          }
        ]
      }
    ],
    "programs": [
      {
        "id": 3
      }
    ]
  }
}"#;

    let v: Value = serde_json::from_str(data).expect("Unable to parse");
    let sessions = v["data"]["sessions"].as_array().unwrap();
    let programs = v["data"]["programs"].as_array().unwrap();

    for program in programs {
        // 将program.id转为具体数值类型,避免Value比较的潜在类型不匹配问题
        let program_id = program["id"].as_i64().unwrap();

        // 遍历所有session,筛选出匹配的programData项
        let matched_program_data: Vec<&Value> = sessions
            .iter()
            // 展开每个session的programData数组,将嵌套数组转为平铺的元素流
            .flat_map(|session| session["programData"].as_array().unwrap())
            // 筛选programRefId与当前program.id匹配的项
            .filter(|data_item| data_item["programRefId"].as_i64().unwrap() == program_id)
            .collect();

        println!("匹配到的programData项: {:?}", matched_program_data);
    }
}

关键修正点说明

  • 用flat_map处理嵌套数组:把每个session内部的programData数组展开,让后续的筛选逻辑能直接遍历到单个programData元素。
  • 统一数值类型:将program.id和programRefId都转为i64类型,确保比较操作的类型一致性,避免serde_json::Value不同子类型无法比较的报错。
  • 明确集合类型:给collect()指定Vec<&Value>类型,让Rust能正确推断最终生成的集合类型。

内容的提问来源于stack exchange,提问作者HBCondo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 12:50:07