orx_iterable/iterable.rs
1use crate::transformations::{
2 Chained, Cloned, Copied, Enumerated, FilterMapped, Filtered, FlatMapped, Flattened, Fused,
3 Mapped, MappedWhile, Reversed, Skipped, SkippedWhile, SteppedBy, Taken, TakenWhile, Zipped,
4};
5
6/// An `Iterable` is any type which can return a new iterator that yields elements of the associated type [`Item`] every time [`iter`] method is called.
7///
8/// [`Item`]: crate::Iterable::Item
9/// [`iter`]: crate::Iterable::iter
10///
11/// Notice that this is the least restrictive and most general iterable definition.
12///
13/// Three categories of types implement the Iterable trait:
14///
15/// * references of collections
16/// * cloneable iterators
17/// * lazy generators
18///
19/// # Auto Implementations
20///
21/// ## References of collections
22///
23/// First, consider a collection type `X` storing elements of type `T`.
24/// Provided that the following implementation is provided:
25///
26/// * `&X: IntoIterator<Item = &T>`
27///
28/// Then, `&X` implements `Iterable<Item = &T>`.
29///
30/// In other words, a reference of a collection is an `Iterable`.
31///
32/// ## Cloneable iterators
33///
34/// Second, consider an iterator that can be cloned; i.e., `Iterator + Clone`.
35/// This iterator can be converted into an `Iterable` which can be iterated over
36/// repeatedly by calling `into_iterable` method.
37///
38/// ## Lazy Generators
39///
40/// Third, consider types iterators of which create values on the fly during the
41/// iteration. One such example is the range.
42/// Consider, for instance, the range 3..7.
43/// Although it looks like a collection, it does not hold elements (3, 4, 5, 6) anywhere in memory. These elements are produced on the fly during the iteration.
44/// `Iterable` trait implementations for the ranges are provided in this crate.
45///
46/// For similar custom types, the trait needs to be implemented explicitly.
47///
48/// # Examples
49///
50/// ```
51/// use orx_iterable::*;
52/// use arrayvec::ArrayVec;
53/// use smallvec::{smallvec, SmallVec};
54/// use std::collections::{BTreeSet, BinaryHeap, HashSet, LinkedList, VecDeque};
55///
56/// struct Stats {
57/// count: usize,
58/// mean: i64,
59/// std_dev: i64,
60/// }
61///
62/// /// we need multiple iterations over numbers to compute the stats
63/// fn statistics(numbers: impl Iterable<Item = i64>) -> Stats {
64/// let count = numbers.iter().count() as i64;
65/// let sum = numbers.iter().sum::<i64>();
66/// let mean = sum / count;
67/// let sum_sq_errors: i64 = numbers.iter().map(|x| (x - mean) * (x - mean)).sum();
68/// let std_dev = f64::sqrt(sum_sq_errors as f64 / (count - 1) as f64) as i64;
69/// Stats {
70/// count: count as usize,
71/// mean,
72/// std_dev,
73/// }
74/// }
75///
76/// // collections as Iterable
77///
78/// let x = [3, 5, 7];
79/// statistics(x.copied()); // see Iterable's transformation methods such as copied, mapped, etc.
80///
81/// let x = vec![3, 5, 7];
82/// statistics(x.copied());
83///
84/// let x = LinkedList::from_iter([3, 5, 7]);
85/// statistics(x.copied());
86///
87/// let x = VecDeque::from_iter([3, 5, 7]);
88/// statistics(x.copied());
89///
90/// let x = HashSet::<_>::from_iter([3, 5, 7]);
91/// statistics(x.copied());
92///
93/// let x = BTreeSet::from_iter([3, 5, 7]);
94/// statistics(x.copied());
95///
96/// let x = BinaryHeap::from_iter([3, 5, 7]);
97/// statistics(x.copied());
98///
99/// let x: SmallVec<[_; 128]> = smallvec![3, 5, 7];
100/// statistics(x.copied());
101///
102/// let mut x = ArrayVec::<_, 16>::new();
103/// x.extend([3, 5, 7]);
104/// statistics(x.copied());
105///
106/// // cloneable iterators as Iterable
107///
108/// let x = (0..10).map(|x| x * 2).into_iterable();
109/// statistics(x);
110///
111/// let x = vec![1, 2, 3];
112/// let y = x
113/// .iter()
114/// .copied()
115/// .filter(|x| x % 2 == 1)
116/// .flat_map(|x| [-x, x])
117/// .into_iterable();
118/// statistics(y);
119///
120/// // lazy generators as Iterable
121///
122/// statistics(7..21i64);
123/// ```
124///
125/// The following example represents an explicit implementation of the Iterable
126/// trait for a lazy generator, which generates a sequence of Fibonacci numbers
127/// up to a set bound.
128///
129/// ```
130/// use orx_iterable::*;
131///
132/// struct FibUntilIter {
133/// curr: u32,
134/// next: u32,
135/// until: u32,
136/// }
137///
138/// impl Iterator for FibUntilIter {
139/// type Item = u32;
140///
141/// fn next(&mut self) -> Option<Self::Item> {
142/// let current = self.curr;
143/// self.curr = self.next;
144/// self.next = current + self.next;
145/// match current > self.until {
146/// false => Some(current),
147/// true => None,
148/// }
149/// }
150/// }
151///
152/// struct FibUntil(u32);
153///
154/// impl Iterable for FibUntil {
155/// type Item = u32;
156///
157/// type Iter = FibUntilIter;
158///
159/// fn iter(&self) -> Self::Iter {
160/// FibUntilIter { curr: 0, next: 1, until: self.0 }
161/// }
162/// }
163///
164/// let fib = FibUntil(10); // Iterable
165///
166/// assert_eq!(fib.iter().count(), 7);
167/// assert_eq!(fib.iter().max(), Some(8));
168/// assert_eq!(fib.iter().collect::<Vec<_>>(), [0, 1, 1, 2, 3, 5, 8]);
169/// ```
170pub trait Iterable {
171 /// Type of the item that the iterators created by the [`iter`] method yields.
172 ///
173 /// [`iter`]: crate::Iterable::iter
174 type Item;
175
176 /// Type of the iterator created by the [`iter`] method.
177 ///
178 /// [`iter`]: crate::Iterable::iter
179 type Iter: Iterator<Item = Self::Item>;
180
181 /// Creates a new iterator from this iterable yielding elements of type `Iterable::Item`.
182 fn iter(&self) -> Self::Iter;
183
184 // provided
185
186 /// Takes two iterables and creates a new iterable over both in sequence.
187 ///
188 /// In other words, it links two iterators together, in a chain.
189 ///
190 /// [`once`] is commonly used to adapt a single value into a chain of other kinds of iteration.
191 ///
192 /// [`once`]: crate::once
193 ///
194 /// # Examples
195 ///
196 /// ```
197 /// use orx_iterable::*;
198 ///
199 /// let a = vec!['a', 'b'];
200 /// let b = ['c', 'd', 'e'];
201 ///
202 /// let it = a.chained(&b).copied();
203 /// assert_eq!(it.iter().count(), 5);
204 /// assert_eq!(it.iter().collect::<Vec<_>>(), vec!['a', 'b', 'c', 'd', 'e']);
205 /// ```
206 fn chained<I>(self, other: I) -> Chained<Self, I>
207 where
208 Self: Sized,
209 I: Iterable<Item = Self::Item>,
210 {
211 Chained {
212 it1: self,
213 it2: other,
214 }
215 }
216
217 /// Creates an iterable, iterators of which clone all of its elements.
218 ///
219 /// This is useful when you have an iterable over &T, but you need an iterable over T.
220 ///
221 /// # Examples
222 ///
223 /// ```
224 /// use orx_iterable::*;
225 ///
226 /// fn count_and_sum(data: impl Iterable<Item = i32>) -> (usize, i32) {
227 /// (data.iter().count(), data.iter().sum())
228 /// }
229 ///
230 /// let a = vec![1, 3, 7, 15];
231 ///
232 /// assert_eq!((4, 26), count_and_sum(a.cloned()));
233 ///
234 /// assert_eq!((3, 11), count_and_sum(a.filtered(|x| **x < 10).cloned()));
235 /// ```
236 fn cloned<'a, T>(self) -> Cloned<'a, T, Self>
237 where
238 Self: Sized + Iterable<Item = &'a T>,
239 T: Clone,
240 {
241 Cloned { it: self }
242 }
243
244 /// Creates an iterable, iterators of which copy all of its elements.
245 ///
246 /// This is useful when you have an iterable over &T, but you need an iterable over T.
247 ///
248 /// # Examples
249 ///
250 /// ```
251 /// use orx_iterable::*;
252 ///
253 /// fn count_and_sum(data: impl Iterable<Item = i32>) -> (usize, i32) {
254 /// (data.iter().count(), data.iter().sum())
255 /// }
256 ///
257 /// let a = vec![1, 3, 7, 15];
258 ///
259 /// assert_eq!((4, 26), count_and_sum(a.copied()));
260 ///
261 /// assert_eq!((3, 11), count_and_sum(a.filtered(|x| **x < 10).copied()));
262 /// ```
263 fn copied<'a, T>(self) -> Copied<'a, T, Self>
264 where
265 Self: Sized + Iterable<Item = &'a T>,
266 T: Copy,
267 {
268 Copied { it: self }
269 }
270
271 /// Creates an iterable which gives the current iteration count as well as the next value.
272 ///
273 /// The iterators created by enumerated iterable yields pairs `(i, val)`,
274 /// where `i` is the current index of iteration and `val` is the value returned by the iterator.
275 ///
276 /// # Examples
277 ///
278 /// ```
279 /// use orx_iterable::*;
280 ///
281 /// let a = ['a', 'b', 'c'];
282 /// let it = a.enumerated();
283 ///
284 /// assert_eq!(it.iter().count(), 3);
285 /// assert_eq!(it.iter().collect::<Vec<_>>(), vec![(0, &'a'), (1, &'b'), (2, &'c')]);
286 /// ```
287 fn enumerated(self) -> Enumerated<Self>
288 where
289 Self: Sized,
290 {
291 Enumerated { it: self }
292 }
293
294 /// Creates an iterable that both filters and maps.
295 ///
296 /// Iterators of the returned iterable yields only the values for which the supplied closure returns `Some(value)`.
297 ///
298 /// `filter_mapped` can be used to make chains of `filtered` and `mapped` more concise.
299 /// The example below shows how a `mapped().filtered().mapped()` can be shortened to a single call
300 /// to `filter_mapped`.
301 ///
302 /// # Examples
303 ///
304 /// ```
305 /// use orx_iterable::*;
306 ///
307 /// let a = ["1", "two", "NaN", "four", "5"];
308 ///
309 /// let it = a.filter_mapped(|s| s.parse::<u32>().ok());
310 ///
311 /// assert_eq!(it.iter().count(), 2);
312 /// assert_eq!(it.iter().collect::<Vec<_>>(), vec![1, 5]);
313 /// ```
314 fn filter_mapped<M, U>(self, filter_map: M) -> FilterMapped<Self, M, U>
315 where
316 Self: Sized,
317 M: Fn(Self::Item) -> Option<U> + Copy,
318 {
319 FilterMapped {
320 it: self,
321 filter_map,
322 }
323 }
324
325 /// Creates an iterable which uses a closure to determine if an element should be yielded.
326 ///
327 /// Given an element the closure must return true or false. Iterators of the returned iterable
328 /// will yield only the elements for which the closure returns true.
329 ///
330 /// # Examples
331 ///
332 /// ```
333 /// use orx_iterable::*;
334 ///
335 /// let a = [0i32, 1, 2];
336 ///
337 /// let it = a.filtered(|x| x.is_positive());
338 ///
339 /// assert_eq!(it.iter().count(), 2);
340 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2]);
341 /// ```
342 fn filtered<P>(self, filter: P) -> Filtered<Self, P>
343 where
344 Self: Sized,
345 P: Fn(&Self::Item) -> bool + Copy,
346 {
347 Filtered { it: self, filter }
348 }
349
350 /// Creates an iterable that works like map, but flattens nested structure.
351 ///
352 /// You can think of `flat_mapped(f)` as the semantic equivalent of mapping,
353 /// and then flattening as in `mapped(f).flattened()`.
354 ///
355 /// Another way of thinking about `flat_mapped()`:
356 ///
357 /// * `mapped`’s closure returns one item for each element, and
358 /// * `flat_map()`’s closure returns an iterator for each element.
359 ///
360 /// # Examples
361 ///
362 /// ```
363 /// use orx_iterable::*;
364 ///
365 /// let words = ["al", "p", "ha"];
366 ///
367 /// let it = words.flat_mapped(|s| s.chars());
368 ///
369 /// assert_eq!(it.iter().count(), 5);
370 /// assert_eq!(it.iter().collect::<String>().as_str(), "alpha");
371 /// ```
372 fn flat_mapped<M, U>(self, flat_map: M) -> FlatMapped<Self, M, U>
373 where
374 Self: Sized,
375 U: IntoIterator,
376 M: Fn(Self::Item) -> U + Copy,
377 {
378 FlatMapped { it: self, flat_map }
379 }
380
381 /// Creates an iterable that flattens nested structure.
382 ///
383 /// This is useful when you have an iterable of iterators or an iterable of things that can be
384 /// turned into iterators and you want to remove one level of indirection.
385 ///
386 /// # Examples
387 ///
388 /// ```
389 /// use orx_iterable::*;
390 ///
391 /// let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
392 ///
393 /// let it = data.flattened();
394 ///
395 /// assert_eq!(it.iter().count(), 6);
396 /// assert_eq!(it.iter().sum::<u32>(), 21);
397 /// ```
398 fn flattened(self) -> Flattened<Self>
399 where
400 Self: Sized,
401 Self::Item: IntoIterator,
402 {
403 Flattened { it: self }
404 }
405
406 /// Creates an iterable which ends after the first `None`.
407 ///
408 /// After an iterator returns `None`, future calls may or may not yield `Some(T)` again.
409 /// fuse() adapts an iterator, ensuring that after a `None` is given, it will always return `None` forever.
410 ///
411 /// Note that the Fuse wrapper is a no-op on iterators that implement the FusedIterator trait.
412 /// fuse() may therefore behave incorrectly if the FusedIterator trait is improperly implemented.
413 fn fused(self) -> Fused<Self>
414 where
415 Self: Sized,
416 {
417 Fused { it: self }
418 }
419
420 /// Creates an iterable that both yields elements based on a predicate and maps.
421 ///
422 /// `map_while()` takes a closure as an argument. It will call this closure on each element
423 /// of the iterator, and yield elements while it returns `Some(_)`.
424 ///
425 /// # Examples
426 ///
427 /// ```
428 /// use orx_iterable::*;
429 ///
430 /// let a = [0, 1, 2, -3, 4, 5, -6];
431 ///
432 /// let it = a.mapped_while(|x| u32::try_from(*x).ok());
433 ///
434 /// assert_eq!(it.iter().count(), 3);
435 /// assert_eq!(it.iter().collect::<Vec<_>>(), [0, 1, 2]);
436 /// ```
437 fn mapped_while<M, U>(self, map_while: M) -> MappedWhile<Self, M, U>
438 where
439 Self: Sized,
440 M: Fn(Self::Item) -> Option<U> + Copy,
441 {
442 MappedWhile {
443 it: self,
444 map_while,
445 }
446 }
447
448 /// Takes a closure and creates an iterable which calls that closure on each element.
449 ///
450 /// map() transforms one iterator into another, by means of its argument `map`.
451 /// It produces a new iterable, iterators of which calls this closure on each element of
452 /// the original iterable.
453 ///
454 /// # Example
455 ///
456 /// ```
457 /// use orx_iterable::*;
458 ///
459 /// let a = [1, 3, 6];
460 ///
461 /// let it = a.mapped(|x| 2 * x);
462 ///
463 /// assert_eq!(it.iter().sum::<i32>(), 20);
464 /// assert_eq!(it.iter().collect::<Vec<_>>(), [2, 6, 12]);
465 /// ```
466 fn mapped<M, U>(self, map: M) -> Mapped<Self, M, U>
467 where
468 Self: Sized,
469 M: Fn(Self::Item) -> U + Copy,
470 {
471 Mapped { it: self, map }
472 }
473
474 /// Creates an iterable iterators of which reverses the traversal direction.
475 ///
476 /// This is only possible if the iterable's iterator type has an end,
477 /// so `reversed()` only works when `Iterable::Iter` is a `DoubleEndedIterator`.
478 ///
479 /// # Example
480 ///
481 /// ```
482 /// use orx_iterable::*;
483 ///
484 /// let a = [1, 2, 3];
485 ///
486 /// let it = a.reversed();
487 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&3, &2, &1]);
488 ///
489 /// let it = it.reversed();
490 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2, &3]);
491 /// ```
492 fn reversed(self) -> Reversed<Self>
493 where
494 Self: Sized,
495 Self::Iter: DoubleEndedIterator,
496 {
497 Reversed { it: self }
498 }
499
500 /// Creates an iterable, iterators of which skip the first `n` elements.
501 ///
502 /// Created iterators skip elements until n elements are skipped or the end of the iterator
503 /// is reached (whichever happens first).
504 /// After that, all the remaining elements are yielded. In particular, if the original iterator
505 /// is too short, then the returned iterator is empty.
506 ///
507 /// # Examples
508 ///
509 /// ```
510 /// use orx_iterable::*;
511 ///
512 /// let a = [1, 2, 3];
513 ///
514 /// let it = a.skipped(2);
515 ///
516 /// assert_eq!(it.iter().count(), 1);
517 /// assert_eq!(it.iter().next(), Some(&3));
518 /// ```
519 fn skipped(self, n: usize) -> Skipped<Self>
520 where
521 Self: Sized,
522 {
523 Skipped { it: self, n }
524 }
525
526 /// Creates an iterable, iterators of which skip elements based on a predicate.
527 ///
528 /// `skipped_while()` takes a closure as an argument. It will call this closure on each element
529 /// of the iterator, and ignore elements until it returns false.
530 ///
531 /// After false is returned, `skip_while`’s job is over, and the rest of the elements are yielded.
532 ///
533 /// # Examples
534 ///
535 /// ```
536 /// use orx_iterable::*;
537 ///
538 /// let a = [-1i32, 0, 1];
539 ///
540 /// let it = a.skipped_while(|x| x.is_negative());
541 ///
542 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &1]);
543 /// ```
544 fn skipped_while<P>(self, skip_while: P) -> SkippedWhile<Self, P>
545 where
546 Self: Sized,
547 P: Fn(&Self::Item) -> bool + Copy,
548 {
549 SkippedWhile {
550 it: self,
551 skip_while,
552 }
553 }
554
555 /// Creates an iterable starting at the same point, but stepping by the given amount at each iteration.
556 ///
557 /// The first element of the iterator will always be returned, regardless of the step given.
558 ///
559 /// # Examples
560 ///
561 /// ```
562 /// use orx_iterable::*;
563 ///
564 /// let a = [0, 1, 2, 3, 4, 5];
565 ///
566 /// let it = a.stepped_by(2);
567 ///
568 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &2, &4]);
569 /// ```
570 fn stepped_by(self, step: usize) -> SteppedBy<Self>
571 where
572 Self: Sized,
573 {
574 SteppedBy { it: self, step }
575 }
576
577 /// Creates an iterable whose iterators yield the first `n` elements, or fewer if the underlying iterator ends sooner.
578 ///
579 /// # Examples
580 ///
581 /// ```
582 /// use orx_iterable::*;
583 ///
584 /// let a = [1, 2, 3];
585 ///
586 /// let it = a.taken(2);
587 ///
588 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2]);
589 /// ```
590 fn taken(self, n: usize) -> Taken<Self>
591 where
592 Self: Sized,
593 {
594 Taken { it: self, n }
595 }
596
597 /// Creates an iterable, iterators of which yield elements based on a predicate.
598 ///
599 /// `taken_while()` takes a closure as an argument.
600 /// It will call this closure on each element of the iterator, and yield elements while it returns true.
601 ///
602 /// After false is returned, the rest of the elements are ignored.
603 ///
604 /// # Examples
605 ///
606 /// ```
607 /// use orx_iterable::*;
608 ///
609 /// let a = [-1i32, 0, 1];
610 ///
611 /// let it = a.taken_while(|x| x.is_negative());
612 ///
613 /// assert_eq!(it.iter().count(), 1);
614 /// assert_eq!(it.iter().next(), Some(&-1));
615 /// ```
616 fn taken_while<P>(self, take_while: P) -> TakenWhile<Self, P>
617 where
618 Self: Sized,
619 P: Fn(&Self::Item) -> bool + Copy,
620 {
621 TakenWhile {
622 it: self,
623 take_while,
624 }
625 }
626
627 /// ‘Zips up’ two iterables into a single iterable of pairs.
628 ///
629 /// The zipped iterable creates zipped iterators.
630 ///
631 /// If either iterator returns None, next from the zipped iterator will return None.
632 /// If the zipped iterator has no more elements to return then each further attempt to advance it will first try to
633 /// advance the first iterator at most one time and if it still yielded an item try to advance the second iterator
634 /// at most one time.
635 ///
636 /// # Examples
637 ///
638 /// ```
639 /// use orx_iterable::*;
640 ///
641 /// let a1 = [1, 2, 3];
642 /// let b1 = [4, 5, 6, 7];
643 ///
644 /// let it = a1.zipped(&b1);
645 ///
646 /// assert_eq!(it.iter().count(), 3);
647 /// assert_eq!(it.iter().collect::<Vec<_>>(), [(&1, &4), (&2, &5), (&3, &6)]);
648 /// ```
649 fn zipped<I>(self, other: I) -> Zipped<Self, I>
650 where
651 Self: Sized,
652 I: Iterable,
653 {
654 Zipped {
655 it1: self,
656 it2: other,
657 }
658 }
659}
660
661// impl
662
663impl<'a, X> Iterable for &'a X
664where
665 &'a X: IntoIterator,
666{
667 type Item = <&'a X as IntoIterator>::Item;
668
669 type Iter = <&'a X as IntoIterator>::IntoIter;
670
671 fn iter(&self) -> Self::Iter {
672 self.into_iter()
673 }
674}
675
676impl<'a, X> Iterable for &'a [X] {
677 type Item = &'a X;
678
679 type Iter = core::slice::Iter<'a, X>;
680
681 fn iter(&self) -> Self::Iter {
682 <[X]>::iter(self)
683 }
684}