递归 impl Extend for HashMap<_, HashSet<_>> 其中集合组合而不是覆盖?



我正在努力使我的代码适应我之前问题的解决方案。基本上,我有一个HashMap<String, HashSet<String>>,它应该是由reson的par_extend生成的。问题是密钥重复,在这种情况下,我希望HashSets被组合,而不是被覆盖。换句话说,有没有一种方法可以在这里添加一个自定义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);
}
}
}

游乐场

最新更新