cs_utils/test/
pick_random.rs1use std::collections::HashSet;
2use rand::distributions::uniform::SampleRange;
3
4use crate::random_number;
5
6pub fn pick_random<'a, T>(
37 collection: &'a [T],
38 items_count: usize,
39) -> Vec<&'a T> {
40 let iter = collection.iter();
41 let (_, len) = iter.size_hint();
42 let len = len.expect("Gennot get iterator length.");
43
44 assert!(
45 items_count <= len,
46 "Count must be smaller or equal to item length.",
47 );
48
49 let mut set = HashSet::new();
50 while set.len() < items_count {
51 set.insert(
52 random_number(0..len)
53 );
54 };
55
56 let result = iter
57 .enumerate()
58 .filter_map(|(index, item)| {
59 if set.contains(&index) {
60 return Some(item);
61 }
62
63 return None;
64 }).collect();
65
66 return result;
67}
68
69pub fn pick_random_rg<'a, T, R: SampleRange<usize>>(
104 collection: &'a [T],
105 range: R,
106) -> Vec<&'a T> {
107 let items_count = random_number(range);
108
109 return pick_random(collection, items_count);
110
111}
112
113#[cfg(test)]
114mod tests {
115 use crate::traits::Random;
116 use crate::random_number;
117
118 impl Random for u8 {
119 fn random() -> Self {
120 return random_number(0..=u8::MAX);
121 }
122 }
123
124 mod pick_random {
125 use random_vec::random_vec_rg;
126 use crate::{random_number, test::{random_vec, pick_random}};
127
128 #[test]
129 fn picks_random_items_from_vector() {
130 let test_vector: Vec<u8> = random_vec_rg(100..=200);
131 let original_test_vector_length = test_vector.len();
132
133 let items_count = random_number(30..=50);
134 let random_items = pick_random(&test_vector, items_count);
135
136 assert_eq!(
137 random_items.len(),
138 items_count,
139 "Must return vector with {} references.", items_count,
140 );
141
142 assert_eq!(
143 test_vector.len(),
144 original_test_vector_length,
145 "Test vector must not change.",
146 );
147
148 for item in random_items {
149 assert!(
150 test_vector.contains(item),
151 "Test vector must contain random item.",
152 );
153 }
154 }
155
156 #[test]
157 fn picks_random_items_from_slice() {
158 let test_vector: Vec<u8> = random_vec_rg(100..=200);
159 let original_test_vector_length = test_vector.len();
160
161 let items_count = random_number(3..=5);
162 let random_items = pick_random(&test_vector[..], items_count);
163
164 assert_eq!(
165 random_items.len(),
166 items_count,
167 "Must return vector with {} references.", items_count,
168 );
169
170 assert_eq!(
171 test_vector.len(),
172 original_test_vector_length,
173 "Test vector must not change.",
174 );
175
176 for item in random_items {
177 assert!(
178 test_vector.contains(item),
179 "Test vector must contain random item.",
180 );
181 }
182 }
183 }
184
185 mod pick_random_rg {
186 use random_vec::random_vec_rg;
187 use crate::{test::{random_vec, pick_random_rg}};
188
189 #[test]
190 fn picks_random_items_from_vector() {
191 let test_vector: Vec<u8> = random_vec_rg(100..=200);
192 let original_test_vector_length = test_vector.len();
193
194 let random_items = pick_random_rg(&test_vector, 30..=50);
195
196 assert!(
197 random_items.len() >= 30,
198 "Must return vector with at least 30 references.",
199 );
200
201 assert!(
202 random_items.len() <= 50,
203 "Must return vector with at most 50 references.",
204 );
205
206 assert_eq!(
207 test_vector.len(),
208 original_test_vector_length,
209 "Test vector must not change.",
210 );
211
212 for item in random_items {
213 assert!(
214 test_vector.contains(item),
215 "Test vector must contain random item.",
216 );
217 }
218 }
219
220 #[test]
221 fn picks_random_items_from_slice() {
222 let test_vector: Vec<u8> = random_vec_rg(100..=200);
223 let original_test_vector_length = test_vector.len();
224
225 let random_items = pick_random_rg(&test_vector[..], 30..=50);
226
227 assert!(
228 random_items.len() >= 30,
229 "Must return vector with at least 30 references.",
230 );
231
232 assert!(
233 random_items.len() <= 50,
234 "Must return vector with at most 50 references.",
235 );
236
237 assert_eq!(
238 test_vector.len(),
239 original_test_vector_length,
240 "Test vector must not change.",
241 );
242
243 for item in random_items {
244 assert!(
245 test_vector.contains(item),
246 "Test vector must contain random item.",
247 );
248 }
249 }
250 }
251}