Search code examples
rustunionhashset

How can I insert all values of one HashSet into another HashSet?


I have two HashSet<u16>s and I would like to implement a = a U b. If possible, I'd like to use HashSet::union rather than loops or other tweaks.

I tried the following:

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 error message is the following:

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

How can I perform a = a U b?


Solution

  • You don't want union — as you said, it will create a new HashSet. Instead you can use 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}
    }
    

    (Playground)

    Extend::extend is also implemented for other collections, e.g. Vec. The result for Vec will differ because Vec does not honor duplicates in the same way a Set does.