Skip to content

Commit 20b7f57

Browse files
committed
Add Itertools.counts_by
1 parent 573743a commit 20b7f57

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3048,6 +3048,36 @@ pub trait Itertools : Iterator {
30483048
self.for_each(|item| *counts.entry(item).or_default() += 1);
30493049
counts
30503050
}
3051+
3052+
/// Collect the items in this iterator and return a `HashMap` which
3053+
/// contains each item that appears in the iterator and the number
3054+
/// of times it appears,
3055+
/// determining identity using a keying function.
3056+
///
3057+
/// # Examples
3058+
/// ```
3059+
/// # use itertools::Itertools;
3060+
/// # use std::collections::HashMap;
3061+
/// let counts: HashMap<usize, usize> = vec![
3062+
/// (1, "foo"), (1, "bar"), (1, "baz"),
3063+
/// (3, "spam"), (3, "eggs"), (5, "foo")
3064+
/// ].into_iter().counts_by(|(fst,snd)| fst);
3065+
/// assert_eq!(counts[&1], 3);
3066+
/// assert_eq!(counts[&3], 2);
3067+
/// assert_eq!(counts[&5], 1);
3068+
/// assert_eq!(counts.get(&0), None);
3069+
/// ```
3070+
#[cfg(feature = "use_std")]
3071+
fn counts_by<K, F>(self, mut f: F) -> HashMap<K, usize>
3072+
where
3073+
Self: Sized,
3074+
K: Eq + Hash,
3075+
F: FnMut(Self::Item) -> K,
3076+
{
3077+
let mut counts = HashMap::new();
3078+
self.for_each(|item| *counts.entry(f(item)).or_default() += 1);
3079+
counts
3080+
}
30513081
}
30523082

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

0 commit comments

Comments
 (0)