1use itertools::Itertools;
2use std::collections::HashMap;
3use std::hash::Hash;
4
5#[inline]
8pub fn into_counts<T>(source: Vec<T>) -> HashMap<T, usize>
9where
10 T: Eq + Hash,
11{
12 source.into_iter().counts()
13}
14
15#[inline]
18pub fn invert_map<T>(source: HashMap<T, usize>) -> HashMap<usize, Vec<T>>
19where
20 T: Eq + Hash + Clone,
21{
22 let mut m: HashMap<usize, Vec<T>> = HashMap::new();
23 for (key, value) in source {
24 m.entry(value).or_default().push(key);
25 }
26 m
27}
28
29#[inline]
32pub fn into_count_map<T>(source: Vec<T>) -> HashMap<usize, Vec<T>>
33where
34 T: Eq + Hash + Clone,
35{
36 let counts = into_counts(source);
37 invert_map(counts)
38}
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43 use std::collections::HashSet;
44
45 #[test]
46 fn test_into_counts_empty() {
47 let vec: Vec<i32> = Vec::new();
48 let expected: HashMap<i32, usize> = HashMap::new();
49 assert_eq!(into_counts(vec), expected);
50 }
51
52 #[test]
53 fn test_into_counts_single_element() {
54 let vec = vec![1];
55 let mut expected = HashMap::new();
56 expected.insert(1, 1);
57 assert_eq!(into_counts(vec), expected);
58 }
59
60 #[test]
61 fn test_into_counts_multiple_identical_elements() {
62 let vec = vec![1, 1, 1, 1];
63 let mut expected = HashMap::new();
64 expected.insert(1, 4);
65 assert_eq!(into_counts(vec), expected);
66 }
67
68 #[test]
69 fn test_into_counts_mixed_elements() {
70 let vec = vec![1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
71 let mut expected = HashMap::new();
72 expected.insert(1, 1);
73 expected.insert(2, 2);
74 expected.insert(3, 3);
75 expected.insert(4, 4);
76 assert_eq!(into_counts(vec), expected);
77 }
78
79 #[test]
80 fn test_into_counts_non_integer_elements() {
81 let vec = vec!["a", "b", "b", "c", "c", "c"];
82 let mut expected = HashMap::new();
83 expected.insert("a", 1);
84 expected.insert("b", 2);
85 expected.insert("c", 3);
86 assert_eq!(into_counts(vec), expected);
87 }
88
89 #[derive(Hash, Eq, PartialEq, Clone, Debug)]
90 struct TestStruct {
91 value: i32,
92 }
93
94 #[test]
95 fn test_into_counts_custom_struct() {
96 let vec = vec![
97 TestStruct { value: 1 },
98 TestStruct { value: 2 },
99 TestStruct { value: 2 },
100 ];
101 let mut expected = HashMap::new();
102 expected.insert(TestStruct { value: 1 }, 1);
103 expected.insert(TestStruct { value: 2 }, 2);
104 assert_eq!(into_counts(vec), expected);
105 }
106
107 #[test]
108 fn test_invert_map_single_value() {
109 let mut map = HashMap::new();
110 map.insert(1, 1);
111 let mut expected = HashMap::new();
112 expected.insert(1, vec![1]);
113 assert_eq!(invert_map(map), expected);
114 }
115
116 #[test]
117 fn test_invert_map_multiple_values() {
118 let mut map = HashMap::new();
119 map.insert(1, 2);
120 map.insert(2, 2);
121 map.insert(3, 3);
122 let mut expected = HashMap::new();
123 expected.insert(2, vec![1, 2]);
124 expected.insert(3, vec![3]);
125
126 let result = invert_map(map)
128 .into_iter()
129 .map(|(k, v)| (k, v.into_iter().collect::<HashSet<_>>()))
130 .collect::<HashMap<_, _>>();
131
132 let expected = expected
133 .into_iter()
134 .map(|(k, v)| (k, v.into_iter().collect::<HashSet<_>>()))
135 .collect::<HashMap<_, _>>();
136
137 assert_eq!(result, expected);
138 }
139
140 #[test]
141 fn test_invert_map_empty() {
142 let map: HashMap<i32, usize> = HashMap::new();
143 let expected: HashMap<usize, Vec<i32>> = HashMap::new();
144 assert_eq!(invert_map(map), expected);
145 }
146
147 #[test]
148 fn test_into_count_map_empty() {
149 let vec: Vec<i32> = Vec::new();
150 let expected: HashMap<usize, Vec<i32>> = HashMap::new();
151 assert_eq!(into_count_map(vec), expected);
152 }
153
154 #[test]
155 fn test_into_count_map_single_element() {
156 let vec = vec![1];
157 let mut expected = HashMap::new();
158 expected.insert(1, vec![1]);
159 assert_eq!(into_count_map(vec), expected);
160 }
161
162 #[test]
163 fn test_into_count_map_mixed_elements() {
164 let vec = vec![1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
165 let mut expected = HashMap::new();
166 expected.insert(1, vec![1]);
167 expected.insert(2, vec![2]);
168 expected.insert(3, vec![3]);
169 expected.insert(4, vec![4]);
170 for (key, value) in into_count_map(vec) {
172 let expected_set: HashSet<_> = expected.remove(&key).unwrap().into_iter().collect();
173 let result_set: HashSet<_> = value.into_iter().collect();
174 assert_eq!(expected_set, result_set);
175 }
176 }
177
178 #[test]
179 fn test_large_input() {
180 let vec: Vec<i32> = (0..1000).collect();
181 let counts = into_counts(vec.clone());
182 for i in 0..1000 {
183 assert_eq!(counts.get(&i), Some(&1));
184 }
185 let inverted = invert_map(counts);
186 for i in 0..1000 {
187 assert_eq!(inverted.get(&1).unwrap().contains(&i), true);
188 }
189 let count_map = into_count_map(vec);
190 for i in 0..1000 {
191 assert_eq!(count_map.get(&1).unwrap().contains(&i), true);
192 }
193 }
194}
195