Need the items two collections have in common, or the ones only in one of them? Don’t write a for loop with .contains() inside. HashSet has set algebra built in.
The hand-rolled intersection is a loop, a temp Vec, and a membership check you have to get right:
1
2
3
4
5
6
7
8
9
10
11
12
13
| use std::collections::HashSet;
let a: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
let b: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
let mut common = Vec::new();
for x in &a {
if b.contains(x) {
common.push(*x);
}
}
common.sort();
assert_eq!(common, vec![3, 4]);
|
HashSet gives you the four set operations directly. Each returns a lazy iterator that borrows both sets, so nothing is allocated until you collect:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| use std::collections::HashSet;
let a: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
let b: HashSet<i32> = [3, 4, 5, 6].into_iter().collect();
// In both
let mut common: Vec<i32> = a.intersection(&b).copied().collect();
common.sort();
assert_eq!(common, vec![3, 4]);
// In either
let mut all: Vec<i32> = a.union(&b).copied().collect();
all.sort();
assert_eq!(all, vec![1, 2, 3, 4, 5, 6]);
// In a, not in b
let mut only_a: Vec<i32> = a.difference(&b).copied().collect();
only_a.sort();
assert_eq!(only_a, vec![1, 2]);
// In exactly one
let mut either: Vec<i32> = a.symmetric_difference(&b).copied().collect();
either.sort();
assert_eq!(either, vec![1, 2, 5, 6]);
|
The iterators yield &T, which is why .copied() shows up before collect — drop it if you’d rather collect references. (The .sort() calls are only there to make the asserts deterministic; set iteration order isn’t fixed.)
Just asking a yes/no question?
If you only need to know the relationship, not materialize it, three predicates answer in one call without building anything:
1
2
3
4
5
6
7
8
9
| use std::collections::HashSet;
let a: HashSet<i32> = [1, 2, 3, 4].into_iter().collect();
let small: HashSet<i32> = [3, 4].into_iter().collect();
let far: HashSet<i32> = [9, 10].into_iter().collect();
assert!(small.is_subset(&a));
assert!(a.is_superset(&small));
assert!(a.is_disjoint(&far));
|
Whenever you catch yourself looping over one collection to test membership in another, reach for these instead — the intent reads straight off the method name.