Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 704
m.raynal Avatar asked May 15 '19 11:05

m.raynal


People also ask

What is load factor in HashSet?

The load factor is a threshold that decides when the size of the HashSet has to be increased. The default load factor is 0.75, (i.e.), the size of the internal HashMap will be increased once it is 75% filled.

How do you add an element to a HashSet in Java?

HashSet add() Method in Java add() method in Java HashSet is used to add a specific element into a HashSet. This method will add the element only if the specified element is not present in the HashSet else the function will return False if the element is already present in the HashSet.

What happens if you add a duplicate to a HashSet?

HashSet doesn't allow duplicates. If you try to add a duplicate element in HashSet, the old value would be overwritten. HashSet allows null values however if you insert more than one nulls it would still return only one null value.


2 Answers

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.

like image 106
hellow Avatar answered Sep 28 '22 03:09

hellow


// 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

It's because a is a HashSet<u16>, but a.union(&b) is an Iterator<Item=&u16>. Converting a.union(&b) to Iterator<Item=u16> by using .copied() works:

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

As the other mentioned, this will create a new HashSet. In some cases, this might be what you want, but it will make more sense if it's assigned to another variable:

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

// a is unchanged here
like image 33
Daniel Avatar answered Sep 28 '22 04:09

Daniel