The Rust's HashSet::intersection
function creates a new HashSet. How can I update original HashSet by the result of intersection of two HashSets?
fn main() {
// intersecting two HashSets, creating a new HashSet: OK
use std::collections::HashSet;
let a = HashSet::from(["first", "second", "third"]);
let b = HashSet::from(["first", "third", "fifth", "ninth"]);
let intersection: HashSet<_> = a.intersection(&b).collect();
println!("{:?}", intersection);
// intersecting two HashSets, updating the original HashSet: Failed
let mut a = HashSet::from(["first", "second", "third"]);
let b = HashSet::from(["first", "third", "fifth", "ninth"]);
println!("{:?}", a.intersection(&b).collect::<HashSet<_>>());
println!("{:?}", a);
a = a.intersection(&b).collect::<HashSet<_>>(); // doesn't work
// filter: verbose
let mut a = HashSet::from(["first", "second", "third"]);
let b = HashSet::from(["first", "third", "fifth", "ninth"]);
a = a.iter().filter(|&s| b.contains(s)).map(|s| *s).collect::<HashSet<_>>();
println!("{:?}", a);
}
To do this without allocating a new HashSet
, you can use HashSet::retain
and only retain the elements that exist in the second HashSet
:
fn main() {
use std::collections::HashSet;
let mut a = HashSet::from(["first", "second", "third"]);
let b = HashSet::from(["first", "third", "fifth", "ninth"]);
println!("{:?}", a.intersection(&b).collect::<HashSet<_>>());
a.retain(|x| b.contains(x));
println!("{:?}", a);
}
Output:
{"third", "first"}
{"first", "third"}