Collections Rust-如何将数据添加到三重嵌套的HashMap
我试图拆分一堆(50+)json文件,为此,我想根据文件名的元素按频率对它们的值进行分类。我不仅在做这件事,而且在做这件事的时候有点像个新手,因为用Python做这件事不够有趣 为了便于解释,让我们设想如下文件:Collections Rust-如何将数据添加到三重嵌套的HashMap,collections,rust,hashmap,Collections,Rust,Hashmap,我试图拆分一堆(50+)json文件,为此,我想根据文件名的元素按频率对它们的值进行分类。我不仅在做这件事,而且在做这件事的时候有点像个新手,因为用Python做这件事不够有趣 为了便于解释,让我们设想如下文件: a-b-c-d.json { "var":"foo", "array": [ 'one', 'two' ] } b-c-d-f.json { "var&
a-b-c-d.json
{
"var":"foo",
"array": [
'one',
'two'
]
}
b-c-d-f.json
{
"var":"bar",
"array": [
'one',
'three'
]
}
在处理完这两个文件后,我想要得到的数据结构是这样的(请注意,这很可能是我的第一个错误):
我的伪代码大致如下:
HashMap
我得到错误的(实际)代码是:
type ComponentValueElement = HashMap<String, i8>;
type ComponentElement = HashMap<String, ComponentValueElement>;
type ComponentMap = HashMap<String, ComponentElement>;
(...)
fn increase_ocurrence_of_element_in_configuration(component: &String, element: &String, value: &String, final_component_map: &mut ComponentMap) {
final_component_map.entry(component.into()).or_insert( HashMap::new() );
final_component_map[component].entry(element.into()).or_insert(HashMap::new());
final_component_map[component][element].entry(value.into()).or_insert(0);
final_component_map[component][element][value] += 1;
}
type ComponentValueElement=HashMap;
类型ComponentElement=HashMap;
类型ComponentMap=HashMap;
(...)
fn增加\u配置中\u元素\u的\u当前值\u(组件:&String,元素:&String,值:&String,最终\u组件映射:&mut ComponentMap){
最终的组件映射条目(component.into())或插入(HashMap::new());
最终的组件映射[component]。条目(element.into())或插入(HashMap::new());
最终的组件映射[component][element]。条目(value.into())或插入(0);
最终组件映射[组件][元素][值]+=1;
}
错误是:
.entry(element.into())或_insert(HashMap::new())代码>
无法将'std::collections::HashMap'索引中的数据作为可变数据借用
不能像易变的那样借钱
帮助:修改索引内容需要trait`IndexMut',但没有为`std::collections::HashMap'实现`
.entry(value.into())或_insert(0)代码>
无法将'std::collections::HashMap'索引中的数据作为可变数据借用
不能像易变的那样借钱
帮助:修改索引内容需要trait`IndexMut',但没有为`std::collections::HashMap'实现`
+=1代码>
cannot assign to data in an index of `std::collections::HashMap<std::string::String, i8>`
cannot assign
help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, i8>`
无法分配给'std::collections::HashMap'索引中的数据`
无法分配
帮助:修改索引内容需要trait`IndexMut',但没有为`std::collections::HashMap'实现`
我本以为在Rust:D中编写映射会更容易:要让漂亮的嵌套HashMap充满值,我到底需要做什么
非常感谢 API的入口点的一部分是,您可以在不必再次查找的情况下对入口进行变异。您可以将这些查找链接在一起,如下所示:
fn increase_ocurrence_of_element_in_configuration(
component: &str,
element: &str,
value: &str,
final_component_map: &mut ComponentMap,
) {
*final_component_map
.entry(component.into())
.or_default()
.entry(element.into())
.or_default()
.entry(value.into())
.or_default() += 1;
}
使用一个类型为hashmap
的hashmap可能会更有效。。。这是一件事吗D我将如何添加内容?入口界面的工作原理是否相同?另一个问题可能是映射的初始化,因为我迭代了所有json文件,分割并创建了HashMap的第一层(也通过.entry().或_insert()
),类似的操作是否有效取决于您希望支持的访问模式。例如,如果您想在所有map[a]
上迭代,您可能需要使用嵌套映射。是的,有不同的优点和缺点。例如,使用平面结构,删除整个分支会比较慢。我现在不需要迭代,我只需要一个排序报告,这样我就可以拆分文件。因此,至少在我看来,初始设置效果更好。但是知道你可以用元组做HashMaps——这是我以前没有想到的——本身就很有价值。谢谢@PeterHall!这就像是针对entry()
API.:)的电视广告您可以使用或_default()
而不是或_insert(HashMap::new())
将其缩短。(也可能更快,因为或_default()
相当于或_insert_with(| | HashMap::default())
,所以它只在条目为空时调用HashMap::new()
始终创建空hashmap,并依靠优化器优化创建,这可能会发生,也可能不会发生,具体取决于优化器。)@user4815162342 Updated。那好多了。谢谢你们,这确实解决了问题!!
cannot borrow data in an index of `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>` as mutable
cannot borrow as mutable
help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, std::collections::HashMap<std::string::String, i8>>`
cannot assign to data in an index of `std::collections::HashMap<std::string::String, i8>`
cannot assign
help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<std::string::String, i8>`
fn increase_ocurrence_of_element_in_configuration(
component: &str,
element: &str,
value: &str,
final_component_map: &mut ComponentMap,
) {
*final_component_map
.entry(component.into())
.or_default()
.entry(element.into())
.or_default()
.entry(value.into())
.or_default() += 1;
}