1use std::collections::HashMap;
2use std::hash::Hash;
3
4pub fn count_values<T>(collection: &[T]) -> HashMap<T, usize>
74where
75 T: Hash + Eq + Clone,
76{
77 let mut result = HashMap::new();
78 for item in collection {
79 *result.entry(item.clone()).or_insert(0) += 1;
80 }
81 result
82}
83
84#[cfg(test)]
85mod tests {
86 use crate::common;
87
88 use super::*;
89 use std::collections::HashMap;
90
91 #[derive(Debug, PartialEq, Eq, Hash, Clone)]
92 struct Person {
93 name: String,
94 age: u32,
95 }
96
97 #[test]
98 fn test_count_values_integers() {
99 let numbers = vec![1, 2, 2, 3, 4, 3, 5];
100 let result = count_values(&numbers);
101 let mut expected = HashMap::new();
102 expected.insert(1, 1);
103 expected.insert(2, 2);
104 expected.insert(3, 2);
105 expected.insert(4, 1);
106 expected.insert(5, 1);
107 assert_eq!(result, expected);
108 }
109
110 #[test]
111 fn test_count_values_strings() {
112 let strings = vec!["apple", "banana", "apple", "cherry", "banana"];
113 let result = count_values(&strings);
114 let mut expected = HashMap::new();
115 expected.insert("apple", 2);
116 expected.insert("banana", 2);
117 expected.insert("cherry", 1);
118 assert_eq!(result, expected);
119 }
120
121 #[test]
122 fn test_count_values_with_structs() {
123 let people = vec![
124 Person {
125 name: "Alice".to_string(),
126 age: 25,
127 },
128 Person {
129 name: "Bob".to_string(),
130 age: 30,
131 },
132 Person {
133 name: "Alice".to_string(),
134 age: 25,
135 },
136 Person {
137 name: "Carol".to_string(),
138 age: 35,
139 },
140 ];
141
142 let result = count_values(&people);
143 let mut expected = HashMap::new();
144 expected.insert(
145 Person {
146 name: "Alice".to_string(),
147 age: 25,
148 },
149 2,
150 );
151 expected.insert(
152 Person {
153 name: "Bob".to_string(),
154 age: 30,
155 },
156 1,
157 );
158 expected.insert(
159 Person {
160 name: "Carol".to_string(),
161 age: 35,
162 },
163 1,
164 );
165 assert_eq!(result, expected);
166 }
167
168 #[test]
169 fn test_count_values_empty_collection() {
170 let empty: Vec<i32> = vec![];
171 let result = count_values(&empty);
172 let expected: HashMap<i32, usize> = HashMap::new();
173 assert_eq!(result, expected);
174 }
175
176 #[test]
177 fn test_count_values_no_duplicates() {
178 let collection = vec![1, 2, 3, 4, 5];
179 let result = count_values(&collection);
180 let mut expected = HashMap::new();
181 expected.insert(1, 1);
182 expected.insert(2, 1);
183 expected.insert(3, 1);
184 expected.insert(4, 1);
185 expected.insert(5, 1);
186 assert_eq!(result, expected);
187 }
188
189 #[test]
190 fn test_count_values_all_duplicates() {
191 let collection = vec![2, 2, 2, 2];
192 let result = count_values(&collection);
193 let mut expected = HashMap::new();
194 expected.insert(2, 4);
195 assert_eq!(result, expected);
196 }
197
198 #[test]
199 fn test_count_values_with_optionals() {
200 let collection = vec![Some(1), None, Some(2), Some(1), None, Some(3), Some(2)];
201 let result = count_values(&collection);
202 let mut expected = HashMap::new();
203 expected.insert(Some(1), 2);
204 expected.insert(None, 2);
205 expected.insert(Some(2), 2);
206 expected.insert(Some(3), 1);
207 assert_eq!(result, expected);
208 }
209
210 #[test]
211 fn test_count_values_with_floats() {
212 let float_collection = vec![
213 common::Float(1.1),
214 common::Float(2.2),
215 common::Float(2.2),
216 common::Float(3.3),
217 common::Float(4.4),
218 common::Float(3.3),
219 common::Float(5.5),
220 ];
221 let result = count_values(&float_collection);
222 let mut expected = HashMap::new();
223 expected.insert(common::Float(1.1), 1);
224 expected.insert(common::Float(2.2), 2);
225 expected.insert(common::Float(3.3), 2);
226 expected.insert(common::Float(4.4), 1);
227 expected.insert(common::Float(5.5), 1);
228 assert_eq!(result, expected);
229 }
230
231 #[test]
232 fn test_count_values_with_characters() {
233 let chars = vec!['a', 'b', 'a', 'c', 'b', 'd'];
234 let result = count_values(&chars);
235 let mut expected = HashMap::new();
236 expected.insert('a', 2);
237 expected.insert('b', 2);
238 expected.insert('c', 1);
239 expected.insert('d', 1);
240 assert_eq!(result, expected);
241 }
242
243 #[test]
244 fn test_count_values_with_nan_floats() {
245 let float_collection = vec![
246 common::Float(std::f64::NAN),
247 common::Float(std::f64::INFINITY),
248 common::Float(std::f64::NAN),
249 common::Float(1.0),
250 ];
251 let result = count_values(&float_collection);
252 let mut expected = HashMap::new();
253 expected.insert(common::Float(std::f64::NAN), 2);
254 expected.insert(common::Float(std::f64::INFINITY), 1);
255 expected.insert(common::Float(1.0), 1);
256 assert_eq!(result.get(&common::Float(std::f64::NAN)), Some(&2));
258 assert_eq!(result.get(&common::Float(std::f64::INFINITY)), Some(&1));
259 assert_eq!(result.get(&common::Float(1.0)), Some(&1));
260 }
261}