【发布时间】:2019-12-08 00:35:17
【问题描述】:
我希望从 HashMap<String, Value> 创建一个 Vec<Vec<String>>。 Value 类型来自 serde_json。
预期的输出是:
[
["name"]
["age"]
["phones"]
["phones", "0"]
["phones", "1"]
["friends"]
["friends", "0"]
["friends", "0", "name"]
["friends", "0", "age"]
["friends", "0", "phones"]
["friends", "0", "phones", "0"]
["friends", "0", "phones", "1"]
["friends", "0", "friends"]
["friends", "0", "friends", "0"]
["friends", "0", "friends", "0", "name"]
["friends", "0", "friends", "0", "age"]
["friends", "0", "friends", "0", "phones"]
["friends", "0", "friends", "0", "phones", "0"]
["friends", "0", "friends", "0", "friends"]
["friends", "0", "friends", "1"]
["friends", "0", "friends", "1", "name"]
["friends", "0", "friends", "1", "age"]
["friends", "0", "friends", "1", "phones"]
["friends", "0", "friends", "1", "phones", "0"]
["friends", "0", "friends", "1", "friends"]
["friends", "0", "friends", "2"]
["friends", "0", "friends", "2", "name"]
["friends", "0", "friends", "2", "age"]
["friends", "0", "friends", "2", "phones"]
["friends", "0", "friends", "2", "phones", "0"]
["friends", "0", "friends", "2", "friends"]
];
问题:如何遍历递归/嵌套哈希图中的所有键并匹配上面的预期输出?
use serde_json::{Result, Value};
use std::collections::HashMap;
fn deep_keys(data: HashMap<String, Value>) -> Vec<Vec<String>>{
let mut vec = Vec::new();
vec.push(Vec::new());
// logic
for (str, val) in data {
match &val {
Value::String(string) => vec[0].push(str),
Value::Number(Number) => vec[0].push(str),
Value::Bool(bool) => vec[0].push(str),
_ => {
let mut map = HashMap::new();
for (innerStr, innerVal) in val {
let mut map = HashMap::new();
map.insert(str, innerVal);
deep_keys(map);
}
}
};
}
vec
}
fn main() {
let data = r#"
{
"name": "John Doe",
"age": 43,
"phones": [
"+44 1234567",
"+44 2345678"
],
"friends": [
{
"name": "Jenn Doe",
"age": 15,
"phones": ["+44 1234567", "+44 2345678"],
"friends": [
{
"name": "Richard Carter",
"age": 20,
"phones": ["+1 1234567"],
"friends": []
},
{
"name": "Angus Yik",
"age": 21,
"phones": ["+1 1234567"],
"friends": []
},
{
"name": "Diana White",
"age": 24,
"phones": ["+1 12345673"],
"friends": []
}
]
}
]
}"#;
let v: HashMap<String, Value> = serde_json::from_str(data).expect("error");
println!("{:?}", deep_keys(v));
}
当我尝试使 deep_keys 递归时,它会报告一个关于类型不匹配的错误,我不确定如何修复:
rror[E0277]: `serde_json::value::Value` is not an iterator
--> src/main.rs:17:45
|
17 | for (innerStr, innerVal) in val {
| ^^^ `serde_json::value::Value` is not an iterator
|
= help: the trait `std::iter::Iterator` is not implemented for `serde_json::value::Value`
= note: required by `std::iter::IntoIterator::into_iter`
【问题讨论】:
-
@Shepmaster 对不起,我试图简化问题的 json 并打错了play.rust-lang.org/…
-
您已将此标记为recursion,但我没有看到任何递归函数尝试。如果你尝试一个会发生什么?
-
@Shepmaster 我之前尝试过递归,但我不确定这是否是唯一的解决方法,我无法让它工作。我已经用我的递归尝试更新了答案,但由于强制/静态类型,我没有走得太远。
-
如果它有助于我尝试在 rust 中重新创建 github.com/deoxxa/dotty/blob/master/lib/index.js#L234
-
看到
if (typeof object[k] === "object" && object[k] !== null)这样的行了吗?用模式匹配替换那些。
标签: loops recursion rust hashmap serde