rust - 如何组合(包括嵌套数组值)两个 serde_yaml::Value 对象?
问题描述
我无法创建一个递归函数来解析两个 serde_yaml::Value 变量并将它们组合起来。将它们组合在一个基本级别的对象上很容易,但是子级别的值只是组合值的值。
鉴于:
let original:serde_yaml::Value = serde_yaml::from_str(r#"
keyA:
subKeyA:
- A
- B
- C
keyB: "one"
keyC: "a"
"#
).unwrap();
let add_or_modify_these_values:serde_yaml::Value = serde_yaml::from_str(r#"
keyA:
subKeyA:
- D
subKeyB:
- BA
keyB: "two"
keyC:
- A
- B
"#
).unwrap();
我将如何组合它们以便考虑所有嵌套属性,例如:
keyA:
subKeyA:
- A
- B
- C
- D
subKeyB:
- BA
keyB: "two"
keyC:
- A
- B
当出现复杂情况时(例如,不同的值类型,如 keyC),我宁愿用新的值类型覆盖原始值类型。
编辑:我也在这里查看了 json 的类似问题:如何将两个 JSON 对象与 Rust 合并? 但是该合并方法不会合并数组值,只会覆盖。
解决方案
这是一个清理后的版本(与 一起使用#![feature(let_chains)]
):
fn merge_yaml(a: &mut serde_yaml::Value, b: serde_yaml::Value) {
match (a, b) {
(serde_yaml::Value::Mapping(ref mut a), serde_yaml::Value::Mapping(b)) => {
for (k, v) in b {
if let Some(b_seq) = v.as_sequence()
&& let Some(a_val) = a.get(&k)
&& let Some(a_seq) = a_val.as_sequence()
{
a[&k] = [a_seq.as_slice(), b_seq.as_slice()].concat().into();
continue;
}
if !a.contains_key(&k) {
a.insert(k, v);
}
else {
Self::merge_yaml(&mut a[&k], v);
}
}
}
(a, b) => *a = b,
}
}
推荐阅读
- excel - 需要查找一个值并在其他两个文本框上显示以下单元格
- python - 如何更改 Django 过滤器中的查询参数?
- angular - 角度升级8到9后ng服务失败
- arrays - 在 laravel foreach 循环中传递多个变量
- vuetify.js - 根据对象属性控制 v-list-item
- docker - Apache Airflow:如何使用来自另一个任务的环境变量运行 Docker Operator?
- python - 我的帕斯卡三角程序中这个神秘数字是从哪里来的?
- javascript - 如何禁用 html 范围滑块?
- indexeddb - svelte.dev/repl 似乎不支持 indexedDb(或 localStorage)
- swift - textField 最大长度和邮政编码验证