Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/multiset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,29 @@ where
}
}

/// An iterator visiting all elements in arbitrary order paired with the number of times the
/// item appears.
/// The iterator element type is `(&'a K, usize)`.
///
/// # Examples
///
/// ```
/// use multiset::HashMultiSet;
/// let mut multiset = HashMultiSet::new();
/// multiset.insert(0);
/// multiset.insert(0);
/// multiset.insert(1);
///
/// let mut keys_with_counts: Vec<_> = multiset.iter_counts().collect();
/// keys_with_counts.sort(); // Order is arbitrary
/// assert_eq!(keys_with_counts, vec![(&0, 2), (&1, 1)]);
/// ```
pub fn iter_counts(&self) -> IterCounts<K> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably be done with less code. Something like this should work:

pub fn iter_counts(&self) -> impl Iterator<Item = (&K, usize)> {
    self.elem_counts.iter().map(|(key, &counts)| (key, counts))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's true. The general practice for the standard library has been to provide a concrete struct to return. However, returning an impl trait is a relatively recent change, so that may be considered a new best practice. I'd be willing to go that way. It may be worth considering for the sake of consistency, since we do need custom structs for several of the other methods (i.e. UnionCounts, etc.).

IterCounts {
iter: self.elem_counts.iter(),
}
}

/// Returns true if the multiset contains no elements.
///
/// # Examples
Expand Down Expand Up @@ -342,6 +365,18 @@ where
}
}

pub struct IterCounts<'a, K> {
iter: hash_map::Iter<'a, K, usize>,
}

impl<'a, K> Iterator for IterCounts<'a, K> {
type Item = (&'a K, usize);

fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(key, &count)| (key, count))
}
}

impl<T> Add for HashMultiSet<T>
where
T: Eq + Hash + Clone,
Expand Down