multithreading - Recursive impl Extend for HashMap<_, HashSet<_>> 在哪里组合集合,而不是覆盖?
问题描述
我正在尝试使我的代码适应我之前的问题的解决方案。基本上,我有一个HashMap<String, HashSet<String>>
应该由人造丝的par_extend 生成。问题是键重复,在这种情况下,我希望HashSet
s 被组合,而不是被覆盖。换句话说,有没有办法在impl Extend
此处添加自定义,以便以下代码正确执行?
use std::collections::{HashMap, HashSet};
fn main() {
let mut d: HashMap<String, HashSet<String>> = HashMap::new();
d.extend(vec![1, 2].iter().map(|x| {
let mut z = HashSet::new();
z.insert(x.to_string());
return ("a".into(), z);
}));
assert_eq!(d.get("a").unwrap().len(), 2);
}
解决方案
由于孤儿规则,你不能。但是,您可以定义一个廉价的包装器,Extend
为该包装器实现,进行扩展,然后再次打开原始地图。也许是这样的:
use std::collections::{HashMap, HashSet};
type MapOfSets = HashMap<String, HashSet<String>>;
fn main() {
let mut d: ExtendWrapper = ExtendWrapper::new(HashMap::new());
d.extend(vec![1, 2].iter().map(|x| {
let mut z = HashSet::new();
z.insert(x.to_string());
return ("a".into(), z);
}));
let d = d.into_inner();
assert_eq!(d.get("a").unwrap().len(), 2);
}
struct ExtendWrapper(MapOfSets);
impl ExtendWrapper {
fn new(map: MapOfSets) -> Self {
Self(map)
}
fn into_inner(self) -> MapOfSets {
self.0
}
}
impl Extend<(String, HashSet<String>)> for ExtendWrapper {
fn extend<T>(&mut self, iter: T)
where T: IntoIterator<Item = (String, HashSet<String>)>
{
for (key, set) in iter {
// lifetimes make it infeasible to use the entry api here :(
if let Some(s) = self.0.get_mut(&key) {
s.extend(set);
continue;
}
self.0.insert(key, set);
}
}
}
推荐阅读
- json - 使用 XSLT 转换将 XML 转换为 JSON 后有什么方法可以删除根节点
- node.js - 为什么在使用维度时,Google 分析中的总用户数会有所不同?
- java - 如何在springboot中为DomainArgumentResolver编写测试类?
- git - 撤消 Git 远程分支签出
- python - 如何从一行开始我的 excel 标题(第 10 行是我的数据开始的地方)
- amazon-web-services - 我可以在不使用 Route 53 的情况下将我的域和子域指向 AWS 托管吗?
- php - 正则表达式获取 MTOM 二进制 PDF 内容
- python - Python:绘制从总体到部分的数据图/分布
- microsoft-dynamics - PowerApps:OneDrive 文件夹共享
- python-3.x - 视频仍然不适合 QGraphicsView