检查serde_json值中具有任意深度的键集的值,或者如果Rust为null则添加



使用Id下面的vec之类的东西,可以为json对象添加任意深度。

let set = vec![vec!["123","apple","orange","999"],vec!["1234","apple"],vec!["12345","apple","orange"]];

一旦创建,上面的内容看起来像:

{"123":{"apple":{"orange":"999"}}, "1234":"apple", "12345":{"apple":"orange"}}

我尝试过递归,但我遇到的问题是,我很难通过它进行推理。我遇到的障碍是,如何向上引用价值链?

我这里缺少什么方法吗?我肯定不是唯一一个想这么做的人。。。

如果可能的话,我宁愿不写一些繁琐的东西,这些东西占用了密钥集vec的长度,并且与创建嵌套ex:相匹配

match keys.len() {
2 => json_obj[keys[0]] = json!(keys[1]),
3 => json_obj[keys[0]][keys[1]] = json!(keys[2]),
4 => json_obj[keys[0]][keys[1]][keys[2]] = json!(keys[3]),
...
_=> ()
}

有什么想法吗?

您可以通过迭代来实现这一点——每个循环都要深入到结构中,并深入到迭代器中,但诀窍是,每个步骤都需要知道是否有更多元素超出了最后一个元素,因为最后一个元素需要是字符串而不是对象。我们将使用match构造来完成此操作,该构造同时匹配序列中的下两个项目。

我们可以将函数进一步泛化为";任何可以变成迭代器的东西,该迭代器产生我们可以从中获得&str〃的项;。例如,这将接受String的迭代器或&str的迭代者,或者甚至直接接受两者的Vec

use std::borrow::Borrow;
use serde_json::Value;
fn set_path(
mut obj: &mut Value,
path: impl IntoIterator<Item=impl Borrow<str>>
) {
let mut path = path.into_iter();

// Start with nothing in "a" and the first item in "b".
let mut a;
let mut b = path.next();

loop {
// Shift "b" down into "a" and put the next item into "b".
a = b;
b = path.next();

// Move "a" but borrow "b" because we will use it on the next iteration.
match (a, &b) {
(Some(key), Some(_)) => {
// This level is an object, rebind deeper.
obj = &mut obj[key.borrow()];
}

(Some(s), None) => {
// This is the final string in the sequence.
*obj = Value::String(s.borrow().to_owned());
break;
}

// We were given an empty iterator.
(None, _) => { break; }
}
}
}

(游乐场(

相关内容