Skip to content

Commit cc88a2d

Browse files
committed
Create counts method and tests for it
1 parent 3a28cb6 commit cc88a2d

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2807,6 +2807,30 @@ pub trait Itertools : Iterator {
28072807
{
28082808
multipeek_impl::multipeek(self)
28092809
}
2810+
2811+
/// Collect the items in this iterator and return a `HashMap` which
2812+
/// contains each item that appears in the iterator and the number
2813+
/// of times it appears.
2814+
///
2815+
/// # Examples
2816+
/// ```
2817+
/// # use itertools::Itertools;
2818+
/// let counts = [1, 1, 1, 3, 3, 5].into_iter().counts();
2819+
/// assert_eq!(counts[&1], 3);
2820+
/// assert_eq!(counts[&3], 2);
2821+
/// assert_eq!(counts[&5], 1);
2822+
/// assert_eq!(counts.get(&0), None);
2823+
/// ```
2824+
#[cfg(feature = "use_std")]
2825+
fn counts(self) -> HashMap<Self::Item, usize>
2826+
where
2827+
Self: Sized,
2828+
Self::Item: Eq + Hash,
2829+
{
2830+
let mut counts = HashMap::new();
2831+
self.for_each(|item| *counts.entry(item).or_default() += 1);
2832+
counts
2833+
}
28102834
}
28112835

28122836
impl<T: ?Sized> Itertools for T where T: Iterator { }

tests/test_std.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,3 +913,16 @@ fn tree_fold1() {
913913
assert_eq!(actual, expected);
914914
}
915915
}
916+
917+
#[test]
918+
fn counts() {
919+
let a: [usize; 0] = [];
920+
assert_eq!(0, a.iter().counts().len());
921+
let b = [1, 1, 1, 2, 2, 3];
922+
let b_counts = b.iter().counts();
923+
assert_eq!(3, b_counts.len());
924+
assert_eq!(Some(&3), b_counts.get(&1));
925+
assert_eq!(Some(&2), b_counts.get(&2));
926+
assert_eq!(Some(&1), b_counts.get(&3));
927+
assert_eq!(None, b_counts.get(&4));
928+
}

0 commit comments

Comments
 (0)