1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use crate::Counter;
use num_traits::{One, Zero};
use std::hash::{BuildHasher, Hash};
use std::iter;
use std::ops::AddAssign;
impl<T, N, S> Counter<T, N, S>
where
T: Hash + Eq,
N: AddAssign + Zero + One,
S: BuildHasher + Default,
{
/// Create a new `Counter` initialized with the given iterable.
#[deprecated = "prefer the `FromIterator`/`collect` interface"]
pub fn init<I>(iterable: I) -> Self
where
I: IntoIterator<Item = T>,
{
Self::from_iter(iterable)
}
}
impl<T, N, S> iter::FromIterator<T> for Counter<T, N, S>
where
T: Hash + Eq,
N: AddAssign + Zero + One,
S: BuildHasher + Default,
{
/// Produce a `Counter` from an iterator of items. This is called automatically
/// by [`Iterator::collect()`].
///
/// [`Iterator::collect()`]:
/// https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.collect
///
/// ```rust
/// # use counter::Counter;
/// # use std::collections::HashMap;
/// let counter = "abbccc".chars().collect::<Counter<_>>();
/// let expect = [('a', 1), ('b', 2), ('c', 3)].iter().cloned().collect::<HashMap<_, _>>();
/// assert_eq!(counter.into_map(), expect);
/// ```
///
fn from_iter<I: IntoIterator<Item = T>>(iterable: I) -> Self {
let mut counter = Counter::new();
counter.update(iterable);
counter
}
}
impl<T, N> iter::FromIterator<(T, N)> for Counter<T, N>
where
T: Hash + Eq,
N: AddAssign + Zero,
{
/// Creates a counter from `(item, count)` tuples.
///
/// The counts of duplicate items are summed.
/// ```rust
/// # use counter::Counter;
/// # use std::collections::HashMap;
/// let counter = [('a', 1), ('b', 2), ('c', 3), ('a', 4)].iter()
/// .cloned().collect::<Counter<_>>();
/// let expect = [('a', 5), ('b', 2), ('c', 3)].iter()
/// .cloned().collect::<HashMap<_, _>>();
/// assert_eq!(counter.into_map(), expect);
/// ```
fn from_iter<I: IntoIterator<Item = (T, N)>>(iter: I) -> Self {
let mut cnt = Counter::new();
for (item, item_count) in iter {
let entry = cnt.map.entry(item).or_insert_with(N::zero);
*entry += item_count;
}
cnt
}
}