From bcdde50c054e0a9481e0aceb013e856c9f88f458 Mon Sep 17 00:00:00 2001 From: Harrison McCullough Date: Mon, 14 Oct 2019 20:52:18 -0600 Subject: [PATCH 1/3] Implement union, intersection, union_counts, and intersection_counts The `union` and `union_counts` methods return iterators that yield elements the maximum number of times they appear in either set. This is different from the previously implemented `Add` trait, which yields each element the combined number of times it appears in both sets. The `intersection` and `intersection_counts` methods return iterators that yield elements the minimum number of times they appear in either set. This is distinct from the previously implemented `Sub` trait, which yields each element the number of times it appears in the first set less the number of times it appears in the second. The different between the plain variants and the `_counts` variants is that the former yields only the elements (repeated the correct number of times) while the latter yields a tuple of an element and the count of that element. --- src/multiset.rs | 517 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 517 insertions(+) diff --git a/src/multiset.rs b/src/multiset.rs index dacaec8..6c667d9 100644 --- a/src/multiset.rs +++ b/src/multiset.rs @@ -340,6 +340,231 @@ where pub fn count_of(&self, val: &K) -> usize { self.elem_counts.get(val).map_or(0, |x| *x) } + + /// Returns an iterator over the union of the two sets. + /// + /// This entails visiting each key the maximum number of times it appears in either set. + /// + /// # Examples + /// + /// ``` + /// use multiset::HashMultiSet; + /// + /// let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + /// let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + /// let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + /// union_vec.sort(); // Order is arbitrary + /// assert_eq!(union_vec, vec![1, 1, 2, 2, 3]); + /// ``` + pub fn union<'a>(&'a self, other: &'a HashMultiSet) -> Union<'a, K> { + Union { + set1_iter: self.elem_counts.iter(), + set2_iter: other.elem_counts.iter(), + set1: self, + set2: other, + cur_entry: None, + cur_count: 0, + } + } + + /// Returns an iterator over the intersection of the two sets. + /// + /// This entails visiting each key the minimum number of times it appears in either set. + /// + /// # Examples + /// + /// ``` + /// use multiset::HashMultiSet; + /// + /// let set1: HashMultiSet<_> = [1, 1, 2, 2, 2].iter().cloned().collect(); + /// let set2: HashMultiSet<_> = [1, 2, 2, 3].iter().cloned().collect(); + /// let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + /// intersection_vec.sort(); // Order is arbitrary + /// assert_eq!(intersection_vec, vec![1, 2, 2]); + /// ``` + pub fn intersection<'a>(&'a self, other: &'a HashMultiSet) -> Intersection<'a, K> { + Intersection { + set1_iter: self.elem_counts.iter(), + set2: other, + cur_entry: None, + cur_count: 0, + } + } + + /// Returns an iterator over the union of the two sets. + /// + /// This entails yielding each key with the maximum number of times it appears in either set. + /// + /// # Examples + /// + /// ``` + /// use multiset::HashMultiSet; + /// + /// let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + /// let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + /// let set_union: HashMultiSet<_> = set1 + /// .union_counts(&set2) + /// .map(|(&key, count)| (key, count)) + /// .collect(); + /// assert_eq!(set_union.count_of(&1), 2); + /// assert_eq!(set_union.count_of(&2), 2); + /// assert_eq!(set_union.count_of(&3), 1); + /// ``` + pub fn union_counts<'a>(&'a self, other: &'a HashMultiSet) -> UnionCounts<'a, K> { + UnionCounts { + set1: self, + set2: other, + set1_iter: self.elem_counts.iter(), + set2_iter: other.elem_counts.iter(), + } + } + + /// Return an iterator over the intersection of the two sets. + /// + /// This entails yielding each key with the minimum number of times it appears in either set. If + /// a key only appears in one set, it will not appear at all in the intersection. + /// + /// ``` + /// use multiset::HashMultiSet; + /// + /// let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + /// let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + /// let set_union: HashMultiSet<_> = set1 + /// .intersection_counts(&set2) + /// .map(|(&key, count)| (key, count)) + /// .collect(); + /// assert_eq!(set_union.count_of(&1), 0); + /// assert_eq!(set_union.count_of(&2), 1); + /// assert_eq!(set_union.count_of(&3), 0); + /// ``` + pub fn intersection_counts<'a>( + &'a self, + other: &'a HashMultiSet, + ) -> IntersectionCounts<'a, K> { + IntersectionCounts { + set2: other, + set1_iter: self.elem_counts.iter(), + } + } +} + +pub struct Union<'a, K> { + set1_iter: hash_map::Iter<'a, K, usize>, + set2_iter: hash_map::Iter<'a, K, usize>, + set1: &'a HashMultiSet, + set2: &'a HashMultiSet, + cur_entry: Option<(&'a K, usize)>, + cur_count: usize, +} + +impl<'a, K> Iterator for Union<'a, K> +where + K: Eq + Hash, +{ + type Item = &'a K; + + fn next(&mut self) -> Option { + if let Some((key, count)) = self.cur_entry { + if self.cur_count < count { + self.cur_count += 1; + return Some(key); + } + } + if let Some((new_key, &new_count)) = self.set1_iter.next() { + let max_count = std::cmp::max(new_count, self.set2.count_of(new_key)); + self.cur_entry = Some((new_key, max_count)); + self.cur_count = 0; + return self.next(); + } + while let Some((new_key, &new_count)) = self.set2_iter.next() { + if self.set1.contains(new_key) { + continue; + } + self.cur_entry = Some((new_key, new_count)); + self.cur_count = 0; + return self.next(); + } + None + } +} + +pub struct Intersection<'a, K> { + set1_iter: hash_map::Iter<'a, K, usize>, + set2: &'a HashMultiSet, + cur_entry: Option<(&'a K, usize)>, + cur_count: usize, +} + +impl<'a, K> Iterator for Intersection<'a, K> +where + K: Eq + Hash, +{ + type Item = &'a K; + + fn next(&mut self) -> Option { + if let Some((key, count)) = self.cur_entry { + if self.cur_count < count { + self.cur_count += 1; + return Some(key); + } + } + if let Some((new_key, &new_count)) = self.set1_iter.next() { + let min_count = std::cmp::min(new_count, self.set2.count_of(new_key)); + self.cur_entry = Some((new_key, min_count)); + self.cur_count = 0; + return self.next(); + } + None + } +} + +pub struct UnionCounts<'a, K> { + set1: &'a HashMultiSet, + set2: &'a HashMultiSet, + set1_iter: hash_map::Iter<'a, K, usize>, + set2_iter: hash_map::Iter<'a, K, usize>, +} + +impl<'a, K> Iterator for UnionCounts<'a, K> +where + K: Eq + Hash, +{ + type Item = (&'a K, usize); + + fn next(&mut self) -> Option { + while let Some((key, count)) = self.set1_iter.next() { + let max_count = std::cmp::max(*count, self.set2.count_of(key)); + return Some((key, max_count)); + } + while let Some((key, count)) = self.set2_iter.next() { + if !self.set1.contains(key) { + return Some((key, *count)); + } + } + None + } +} + +pub struct IntersectionCounts<'a, K> { + set2: &'a HashMultiSet, + set1_iter: hash_map::Iter<'a, K, usize>, +} + +impl<'a, K> Iterator for IntersectionCounts<'a, K> +where + K: Eq + Hash, +{ + type Item = (&'a K, usize); + + fn next(&mut self) -> Option { + while let Some((key, count)) = self.set1_iter.next() { + if self.set2.contains(key) { + let min_count = std::cmp::min(*count, self.set2.count_of(key)); + return Some((key, min_count)); + } + } + None + } } impl Add for HashMultiSet @@ -447,6 +672,38 @@ where } } +impl FromIterator<(K, usize)> for HashMultiSet +where + K: Eq + Hash, +{ + /// Creates a new `HashMultiSet` from the elements in an iterable. + /// + /// # Examples + /// + /// Count occurrences of each `char` in `"hello world"`: + /// + /// ``` + /// use multiset::HashMultiSet; + /// use std::iter::FromIterator; + /// + /// let vals = vec!['h','e','l','l','o',' ','w','o','r','l','d']; + /// let multiset: HashMultiSet = FromIterator::from_iter(vals); + /// assert_eq!(1, multiset.count_of(&'h')); + /// assert_eq!(3, multiset.count_of(&'l')); + /// assert_eq!(0, multiset.count_of(&'z')); + /// ``` + fn from_iter(iterable: T) -> HashMultiSet + where + T: IntoIterator, + { + let mut multiset: HashMultiSet = HashMultiSet::new(); + for (elem, count) in iterable.into_iter() { + multiset.insert_times(elem, count); + } + multiset + } +} + impl PartialEq for HashMultiSet where T: Eq + Hash, @@ -556,5 +813,265 @@ mod test_multiset { assert_eq!(set.len(), 1); set.remove(&'d'); assert_eq!(set.len(), 0); + + set.insert_times('e', 2); + assert_eq!(set.len(), 2); + assert_eq!(set.remove_times(&'e', 4), 2); + assert_eq!(set.len(), 0); + } + + #[test] + fn test_union() { + let empty_array: [u32; 0] = []; + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2, 2, 3]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [3, 4, 4].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2, 3, 4, 4]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2, 2].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 2, 2].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2, 2]); + + let set1: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![2, 2, 3]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![1, 1, 2]); + + let set1: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let mut union_vec: Vec<_> = set1.union(&set2).cloned().collect(); + union_vec.sort(); + assert_eq!(union_vec, vec![]); + } + + #[test] + fn test_intersection() { + let empty_array: [u32; 0] = []; + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![2]); + + let set1: HashMultiSet<_> = [1, 1, 2, 2, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 2, 2, 3].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![1, 2, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [3, 4, 4].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![1, 1, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2, 2].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![1, 1, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![1, 1, 2]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 2, 2].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![1, 2]); + + let set1: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![]); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![]); + + let set1: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let mut intersection_vec: Vec<_> = set1.intersection(&set2).cloned().collect(); + intersection_vec.sort(); + assert_eq!(intersection_vec, vec![]); + } + + #[test] + fn test_union_counts() { + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 2); + assert_eq!(set_union.count_of(&3), 1); + + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 3].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 1); + assert_eq!(set_union.count_of(&3), 1); + assert_eq!(set_union.len(), 4); + + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.len(), 2); + + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 1].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 3); + assert_eq!(set_union.len(), 3); + + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 2].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 3); + assert_eq!(set_union.len(), 5); + + let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let empty_array: [u32; 0] = []; + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 1); + assert_eq!(set_union.count_of(&3), 1); + assert_eq!(set_union.len(), 4); + + let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .union_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 1); + assert_eq!(set_union.count_of(&3), 1); + assert_eq!(set_union.len(), 4); + } + + #[test] + fn test_intersection_counts() { + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 1].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .intersection_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.len(), 2); + + let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); + let set2: HashMultiSet<_> = [2, 2, 2].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .intersection_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 0); + assert_eq!(set_union.count_of(&2), 0); + assert_eq!(set_union.len(), 0); + + let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 3].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .intersection_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 0); + assert_eq!(set_union.count_of(&3), 0); + assert_eq!(set_union.len(), 2); + + let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let empty_array: [u32; 0] = []; + let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .intersection_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 0); + assert_eq!(set_union.count_of(&2), 0); + assert_eq!(set_union.count_of(&3), 0); + assert_eq!(set_union.len(), 0); + + let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let set2: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); + let set_union: HashMultiSet<_> = set1 + .intersection_counts(&set2) + .map(|(&key, count)| (key, count)) + .collect(); + assert_eq!(set_union.count_of(&1), 2); + assert_eq!(set_union.count_of(&2), 1); + assert_eq!(set_union.count_of(&3), 1); + assert_eq!(set_union.len(), 4); } } From fdc8166913af7379c46d33ebec2a41bbccfaceba Mon Sep 17 00:00:00 2001 From: Harrison McCullough Date: Fri, 18 Oct 2019 12:08:41 -0600 Subject: [PATCH 2/3] Add documentation comments and export Iterators --- src/lib.rs | 2 +- src/multiset.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 308c2bd..17958fb 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,4 +15,4 @@ mod multiset; -pub use multiset::{HashMultiSet, Iter}; +pub use multiset::{HashMultiSet, Intersection, IntersectionCounts, Iter, Union, UnionCounts}; diff --git a/src/multiset.rs b/src/multiset.rs index 6c667d9..d39196e 100644 --- a/src/multiset.rs +++ b/src/multiset.rs @@ -448,6 +448,8 @@ where } } +/// An iterator over the union of two structs. See [HashMultiSet::union] for +/// more details. pub struct Union<'a, K> { set1_iter: hash_map::Iter<'a, K, usize>, set2_iter: hash_map::Iter<'a, K, usize>, @@ -488,6 +490,8 @@ where } } +/// An iterator over the intersection of two structs. See +/// [HashMultiSet::intersection] for more details. pub struct Intersection<'a, K> { set1_iter: hash_map::Iter<'a, K, usize>, set2: &'a HashMultiSet, @@ -518,6 +522,8 @@ where } } +/// An iterator over the union of two structs. See [HashMultiSet::union] for +/// more details. pub struct UnionCounts<'a, K> { set1: &'a HashMultiSet, set2: &'a HashMultiSet, @@ -545,6 +551,8 @@ where } } +/// An iterator over the intersection of two structs. See +/// [HashMultiSet::intersection] for more details. pub struct IntersectionCounts<'a, K> { set2: &'a HashMultiSet, set1_iter: hash_map::Iter<'a, K, usize>, From 490c857dfeee115ece242ee5ec6770c6ee1c63fc Mon Sep 17 00:00:00 2001 From: Harrison McCullough Date: Sun, 20 Oct 2019 20:30:42 +0200 Subject: [PATCH 3/3] Fix typos in documentation comments --- src/multiset.rs | 52 ++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/multiset.rs b/src/multiset.rs index d39196e..2a55ef8 100644 --- a/src/multiset.rs +++ b/src/multiset.rs @@ -429,13 +429,13 @@ where /// /// let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); /// let set2: HashMultiSet<_> = [2, 2, 3].iter().cloned().collect(); - /// let set_union: HashMultiSet<_> = set1 + /// let set_intersection: HashMultiSet<_> = set1 /// .intersection_counts(&set2) /// .map(|(&key, count)| (key, count)) /// .collect(); - /// assert_eq!(set_union.count_of(&1), 0); - /// assert_eq!(set_union.count_of(&2), 1); - /// assert_eq!(set_union.count_of(&3), 0); + /// assert_eq!(set_intersection.count_of(&1), 0); + /// assert_eq!(set_intersection.count_of(&2), 1); + /// assert_eq!(set_intersection.count_of(&3), 0); /// ``` pub fn intersection_counts<'a>( &'a self, @@ -1031,55 +1031,55 @@ mod test_multiset { fn test_intersection_counts() { let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); let set2: HashMultiSet<_> = [1, 1, 1].iter().cloned().collect(); - let set_union: HashMultiSet<_> = set1 + let set_intersection: HashMultiSet<_> = set1 .intersection_counts(&set2) .map(|(&key, count)| (key, count)) .collect(); - assert_eq!(set_union.count_of(&1), 2); - assert_eq!(set_union.len(), 2); + assert_eq!(set_intersection.count_of(&1), 2); + assert_eq!(set_intersection.len(), 2); let set1: HashMultiSet<_> = [1, 1].iter().cloned().collect(); let set2: HashMultiSet<_> = [2, 2, 2].iter().cloned().collect(); - let set_union: HashMultiSet<_> = set1 + let set_intersection: HashMultiSet<_> = set1 .intersection_counts(&set2) .map(|(&key, count)| (key, count)) .collect(); - assert_eq!(set_union.count_of(&1), 0); - assert_eq!(set_union.count_of(&2), 0); - assert_eq!(set_union.len(), 0); + assert_eq!(set_intersection.count_of(&1), 0); + assert_eq!(set_intersection.count_of(&2), 0); + assert_eq!(set_intersection.len(), 0); let set1: HashMultiSet<_> = [1, 1, 2].iter().cloned().collect(); let set2: HashMultiSet<_> = [1, 1, 3].iter().cloned().collect(); - let set_union: HashMultiSet<_> = set1 + let set_intersection: HashMultiSet<_> = set1 .intersection_counts(&set2) .map(|(&key, count)| (key, count)) .collect(); - assert_eq!(set_union.count_of(&1), 2); - assert_eq!(set_union.count_of(&2), 0); - assert_eq!(set_union.count_of(&3), 0); - assert_eq!(set_union.len(), 2); + assert_eq!(set_intersection.count_of(&1), 2); + assert_eq!(set_intersection.count_of(&2), 0); + assert_eq!(set_intersection.count_of(&3), 0); + assert_eq!(set_intersection.len(), 2); let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); let empty_array: [u32; 0] = []; let set2: HashMultiSet<_> = empty_array.iter().cloned().collect(); - let set_union: HashMultiSet<_> = set1 + let set_intersection: HashMultiSet<_> = set1 .intersection_counts(&set2) .map(|(&key, count)| (key, count)) .collect(); - assert_eq!(set_union.count_of(&1), 0); - assert_eq!(set_union.count_of(&2), 0); - assert_eq!(set_union.count_of(&3), 0); - assert_eq!(set_union.len(), 0); + assert_eq!(set_intersection.count_of(&1), 0); + assert_eq!(set_intersection.count_of(&2), 0); + assert_eq!(set_intersection.count_of(&3), 0); + assert_eq!(set_intersection.len(), 0); let set1: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); let set2: HashMultiSet<_> = [1, 1, 2, 3].iter().cloned().collect(); - let set_union: HashMultiSet<_> = set1 + let set_intersection: HashMultiSet<_> = set1 .intersection_counts(&set2) .map(|(&key, count)| (key, count)) .collect(); - assert_eq!(set_union.count_of(&1), 2); - assert_eq!(set_union.count_of(&2), 1); - assert_eq!(set_union.count_of(&3), 1); - assert_eq!(set_union.len(), 4); + assert_eq!(set_intersection.count_of(&1), 2); + assert_eq!(set_intersection.count_of(&2), 1); + assert_eq!(set_intersection.count_of(&3), 1); + assert_eq!(set_intersection.len(), 4); } }