如何用Rust的serde_json实现任意深度嵌套JSON的构建?
问题描述
给定Rust中的Vec集合:
let set = vec![vec!["123","apple","orange","999"],vec!["1234","apple"],vec!["12345","apple","orange"]];
需要将其转换为任意深度的嵌套JSON对象,最终结构如下:
{"123":{"apple":{"orange":"999"}}, "1234":"apple", "12345":{"apple":"orange"}}
尝试过递归实现,但在处理键链的上层引用时遇到阻碍,希望避免通过匹配键链长度来创建嵌套结构的繁琐写法,寻求可行的解决方案。
解决方案
可以借助serde_json库的Value和Map类型,通过迭代的方式构建嵌套结构,无需手动匹配键链长度,自然适配不同深度的键链:
首先在Cargo.toml中引入依赖:
[dependencies] serde_json = "1.0"
实现代码如下:
use serde_json::{Map, Value}; fn build_nested_json(set: &[Vec<&str>]) -> Value { let mut root = Map::new(); for chain in set { let mut current_map = &mut root; let chain_len = chain.len(); // 遍历键链的前n-1个元素,逐步创建嵌套Map for (i, key) in chain.iter().enumerate().take(chain_len - 1) { // 键不存在则插入空Map,存在则转为可变Map引用进入下一层 let next = current_map.entry(key.to_string()) .or_insert(Value::Object(Map::new())) .as_object_mut() .expect("嵌套链中出现非对象类型值"); current_map = next; } // 将键链最后两个元素作为当前层级的键值对插入 let last_key = chain[chain_len - 2].to_string(); let last_value = Value::String(chain[chain_len - 1].to_string()); current_map.insert(last_key, last_value); } Value::Object(root) } fn main() { let set = vec![ vec!["123","apple","orange","999"], vec!["1234","apple"], vec!["12345","apple","orange"] ]; let result = build_nested_json(&set); println!("{}", serde_json::to_string_pretty(&result).unwrap()); }
代码说明
- 迭代式层级处理:用
current_map跟踪当前所在的嵌套层级,逐个处理键链元素,自动适配2个、3个或更多元素的键链,无需编写长度匹配分支。 - 自动创建嵌套结构:通过
entry方法自动处理键的存在性,不存在则创建空Map,存在则直接复用并进入下一层。 - 类型安全保障:用
as_object_mut()确保嵌套元素始终是Map类型,避免类型错误导致的崩溃。
运行后输出的JSON结构与需求完全一致:
{ "123": { "apple": { "orange": "999" } }, "1234": "apple", "12345": { "apple": "orange" } }
内容的提问来源于stack exchange,提问作者NaN
相关产品推荐
相关产品推荐

