如何将一个 HashSet 的所有值插入到另一个 HashSet 中?

32

我有两个HashSet<u16>,我想实现a = a U b。如果可能的话,我想使用HashSet::union而不是循环或其他调整。

我尝试了以下代码:

use std::collections::HashSet;
let mut a: HashSet<u16> = [1, 2, 3].iter().cloned().collect();
let b: HashSet<u16> = [7, 8, 9].iter().cloned().collect();  

// I can build a union object that contains &u16
let union: HashSet<&u16> = a.union(&b).collect();

// But I can't store the union into a
a = a.union(&b).collect();   //  -> compile error

// of course I can do
for x in &b {
    a.insert(*x);
}
// but I wonder if union could not be used to simply build a union

错误信息如下:
the trait bound 
`std::collections::HashSet<u16>: std::iter::FromIterator<&u16>`
is not satisfied

How can I perform a = a U b?

3个回答

43

你不想使用union,因为它会创建一个新的HashSet。相反,你可以使用Extend::extend

use std::collections::HashSet;

fn main() {
    let mut a: HashSet<u16> = [1, 2, 3].iter().copied().collect();
    let b: HashSet<u16> = [1, 3, 7, 8, 9].iter().copied().collect();

    a.extend(&b);

    println!("{:?}", a); // {8, 3, 2, 1, 7, 9}
}

(游乐场)

Extend::extend为其他集合实现了,例如Vec。对于Vec的结果将不同,因为Vec没有像Set那样尊重重复项。


4
太好了,正是我想要的。它还教会了我不仅应该查找文档中的“方法”部分以找到方法,还要查看结构体实现的特性。Rust确实是一个独立的世界 :-) - m.raynal

2
// But I can't store the union into a
a = a.union(&b).collect();   //  -> compile error

The error message is the following:

the trait bound  `std::collections::HashSet<u16>:
std::iter::FromIterator<&u16>` is not satisfied

这是因为a是一个HashSet<u16>,但a.union(&b)是一个Iterator<Item=&u16>。通过使用.copied()a.union(&b)转换为Iterator<Item=u16>可以解决这个问题:

a = a.union(&b).copied().collect(); // compiles

正如其他人提到的那样,这将创建一个新的 HashSet 。 在某些情况下,这可能是您想要的,但如果将其分配给另一个变量,则会更有意义:

let c: HashSet<u16> = a.union(&b).copied().collect();

// a is unchanged here

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接