Reputation: 2100
I'm using HashSets to find the differences between 2 vectors
let a = vec!["a".to_string(), "b".to_string(), "f".to_string(), "e".to_string()];
let b = vec!["a".to_string(), "c".to_string(), "d".to_string()];
let a_set: HashSet<&String> = HashSet::from_iter(a.iter());
let b_set: HashSet<&String> = HashSet::from_iter(b.iter());
let missing_a = b_set.difference(&a_set).cloned().collect();
let missing_b = a_set.difference(&b_set).cloned().collect();
assert_eq!(missing_a, vec!["c".to_string(), "d".to_string()]);
assert_eq!(missing_b, vec!["f".to_string(), "e".to_string()]);
Currently, the order of missing_a
and missing_b
is not the same each time it is run, so the test can fail.
How can I make sure that HashSet::difference
returns the same output every time?
Upvotes: 1
Views: 320
Reputation: 2100
Thanks to @PitaJ, I decided to use a BTreeSet
:
let a = vec!["a".to_string(), "b".to_string(), "f".to_string(), "e".to_string()];
let b = vec!["a".to_string(), "c".to_string(), "d".to_string()];
let a_set: BTreeSet<&String> = BTreeSet::from_iter(a.iter());
let b_set: BTreeSet<&String> = BTreeSet::from_iter(b.iter());
let missing_a = b_set.difference(&a_set).cloned().collect();
let missing_b = a_set.difference(&b_set).cloned().collect();
assert_eq!(missing_a, vec!["c".to_string(), "d".to_string()]);
assert_eq!(missing_b, vec!["f".to_string(), "e".to_string()]);
Upvotes: 1
Reputation: 169256
Hash-based containers typically do not have deterministic ordering. From the documentation for HashSet::iter()
:
An iterator visiting all elements in arbitrary order.
Just collect the results into a container type that does not take order into account when comparing container values for equality -- such as HashSet
:
fn main() {
let a = vec!["a".to_string(), "b".to_string(), "f".to_string(), "e".to_string()];
let b = vec!["a".to_string(), "b".to_string(), "c".to_string(), "d".to_string()];
let a_set: HashSet<&String> = HashSet::from_iter(a.iter());
let b_set: HashSet<&String> = HashSet::from_iter(b.iter());
let missing_a = b_set.difference(&a_set).cloned().collect::<HashSet<_>>();
let missing_b = a_set.difference(&b_set).cloned().collect::<HashSet<_>>();
assert_eq!(missing_a, HashSet::from_iter([&"c".to_string(), &"d".to_string()]));
assert_eq!(missing_b, HashSet::from_iter([&"f".to_string(), &"e".to_string()]));
}
Upvotes: 3