pub trait Collection {
type Item;
type Iterable<'i>: Iterable<Item = &'i Self::Item>
where Self: 'i;
// Required method
fn as_iterable(&self) -> Self::Iterable<'_>;
// Provided methods
fn iter(&self) -> <Self::Iterable<'_> as Iterable>::Iter { ... }
fn into_chained<I>(self, other: I) -> ChainedCol<Self, I, Self, I>
where Self: Sized,
I: Collection<Item = Self::Item> { ... }
fn into_filtered<P>(self, filter: P) -> FilteredCol<Self, Self, P>
where Self: Sized,
P: Fn(&Self::Item) -> bool + Copy { ... }
fn into_flattened(self) -> FlattenedCol<Self, Self>
where Self: Sized,
Self::Item: IntoIterator,
for<'i> &'i Self::Item: IntoIterator<Item = &'i <Self::Item as IntoIterator>::Item> { ... }
fn into_fused(self) -> FusedCol<Self, Self>
where Self: Sized { ... }
fn into_reversed(self) -> ReversedCol<Self, Self>
where Self: Sized,
for<'b> <Self::Iterable<'b> as Iterable>::Iter: DoubleEndedIterator { ... }
fn into_skipped(self, n: usize) -> SkippedCol<Self, Self>
where Self: Sized { ... }
fn into_skipped_while<P>(
self,
skip_while: P,
) -> SkippedWhileCol<Self, Self, P>
where Self: Sized,
P: Fn(&Self::Item) -> bool + Copy { ... }
fn into_stepped_by(self, step: usize) -> SteppedByCol<Self, Self>
where Self: Sized { ... }
fn into_taken(self, n: usize) -> TakenCol<Self, Self>
where Self: Sized { ... }
fn into_taken_while<P>(self, take_while: P) -> TakenWhileCol<Self, Self, P>
where Self: Sized,
P: Fn(&Self::Item) -> bool + Copy { ... }
}
Expand description
A collection providing the iter
method which returns an iterator over shared references
of elements of the collection.
§Auto Implementations
Consider a collection type X
storing elements of type T
. Provided that the following implementations are provided:
X: IntoIterator<Item = T>
&X: IntoIterator<Item = &T>
Then, X
implements Collection<Item = T>
.
Further, &X
implements Iterable<Item = &T>
.
§Examples
use orx_iterable::*;
use arrayvec::ArrayVec;
use smallvec::{smallvec, SmallVec};
use std::collections::{BinaryHeap, BTreeSet, HashSet, LinkedList, VecDeque};
struct Stats {
count: usize,
mean: i64,
std_dev: i64,
}
/// we need multiple iterations over numbers to compute the stats
fn statistics(numbers: &impl Collection<Item = i64>) -> Stats {
let count = numbers.iter().count() as i64;
let sum = numbers.iter().sum::<i64>();
let mean = sum / count;
let sum_sq_errors: i64 = numbers.iter().map(|x| (x - mean) * (x - mean)).sum();
let std_dev = f64::sqrt(sum_sq_errors as f64 / (count - 1) as f64) as i64;
Stats {
count: count as usize,
mean,
std_dev,
}
}
// example collections that automatically implement Collection
statistics(&[3, 5, 7]);
statistics(&vec![3, 5, 7]);
statistics(&LinkedList::from_iter([3, 5, 7]));
statistics(&VecDeque::from_iter([3, 5, 7]));
statistics(&HashSet::<_>::from_iter([3, 5, 7]));
statistics(&BTreeSet::<_>::from_iter([3, 5, 7]));
statistics(&BinaryHeap::<_>::from_iter([3, 5, 7]));
let x: SmallVec<[_; 128]> = smallvec![3, 5, 7];
statistics(&x);
let mut x = ArrayVec::<_, 16>::new();
x.extend([3, 5, 7]);
statistics(&x);
Required Associated Types§
Sourcetype Iterable<'i>: Iterable<Item = &'i Self::Item>
where
Self: 'i
type Iterable<'i>: Iterable<Item = &'i Self::Item> where Self: 'i
Related type implementing Iterable
trait that the as_iterable
method returns.
If the type of the Collection
is X
, the corresponding Iterable
type is almost
always &X
due to the following relation among the both traits.
Practically, these definitions correspond to the following relations:
- if a collection
X
implements [Collection<Item = T>
], then&X
implements [Iterable<Item = &T>
]; - on the other hand, a type implementing
Iterable
may not be a collection at all, such asRange<usize>
, and hence, does not necessarily implementCollection
.
Required Methods§
Sourcefn as_iterable(&self) -> Self::Iterable<'_>
fn as_iterable(&self) -> Self::Iterable<'_>
Returns the corresponding Iterable
type of this collection, which is often nothing but &Self
.
Provided Methods§
Sourcefn iter(&self) -> <Self::Iterable<'_> as Iterable>::Iter
fn iter(&self) -> <Self::Iterable<'_> as Iterable>::Iter
Creates a new iterator yielding references to the elements of the collection; i.e.,
type of elements is &Collection::Item
.
Sourcefn into_chained<I>(self, other: I) -> ChainedCol<Self, I, Self, I>
fn into_chained<I>(self, other: I) -> ChainedCol<Self, I, Self, I>
Consumes this collection and other
; creates an iterable collection which is a chain of these two
collections.
Note that this method does not change the memory locations of the elements; i.e., the elements still live in two separate collections; however, now chained together.
§Examples
use orx_iterable::*;
let a = vec!['a', 'b'];
let b = ['c', 'd', 'e'];
let mut it = a.into_chained(b);
*it.iter_mut().last().unwrap() = 'x';
assert_eq!(it.iter().count(), 5);
assert_eq!(it.iter().collect::<Vec<_>>(), vec![&'a', &'b', &'c', &'d', &'x']);
Sourcefn into_filtered<P>(self, filter: P) -> FilteredCol<Self, Self, P>
fn into_filtered<P>(self, filter: P) -> FilteredCol<Self, Self, P>
Consumes this collection and creates an iterable collection which is a filtered version of this collection.
§Examples
use orx_iterable::*;
let a = [0i32, 1, 2];
let mut it = a.into_filtered(|x| x.is_positive());
for x in it.iter_mut() {
*x *= 2;
}
assert_eq!(it.iter().count(), 2);
assert_eq!(it.iter().collect::<Vec<_>>(), [&2, &4]);
Sourcefn into_flattened(self) -> FlattenedCol<Self, Self>where
Self: Sized,
Self::Item: IntoIterator,
for<'i> &'i Self::Item: IntoIterator<Item = &'i <Self::Item as IntoIterator>::Item>,
fn into_flattened(self) -> FlattenedCol<Self, Self>where
Self: Sized,
Self::Item: IntoIterator,
for<'i> &'i Self::Item: IntoIterator<Item = &'i <Self::Item as IntoIterator>::Item>,
Consumes this collection and creates an iterable collection which is a flattened version of this collection.
§Examples
use orx_iterable::*;
let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
let mut it = data.into_flattened();
for x in it.iter_mut() {
*x *= 2;
}
assert_eq!(it.iter().count(), 6);
assert_eq!(it.iter().sum::<u32>(), 2 * 21);
Sourcefn into_fused(self) -> FusedCol<Self, Self>where
Self: Sized,
fn into_fused(self) -> FusedCol<Self, Self>where
Self: Sized,
Consumes this collection and creates an iterable collection which is a fused version of this collection.
See core::iter::Fuse
for details on fused iterators.
Sourcefn into_reversed(self) -> ReversedCol<Self, Self>
fn into_reversed(self) -> ReversedCol<Self, Self>
Consumes this collection and creates an iterable collection which is a reversed version of this collection.
§Examples
use orx_iterable::*;
let data = vec![vec![1, 2, 3, 4], vec![5, 6]];
let a = [1, 2, 3];
let it = a.into_reversed();
assert_eq!(it.iter().collect::<Vec<_>>(), [&3, &2, &1]);
let it = it.into_reversed();
assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2, &3]);
Sourcefn into_skipped(self, n: usize) -> SkippedCol<Self, Self>where
Self: Sized,
fn into_skipped(self, n: usize) -> SkippedCol<Self, Self>where
Self: Sized,
Consumes this collection and creates an iterable collection which is skipped-by-n
version of this collection.
§Examples
use orx_iterable::*;
let a = [1, 2, 3, 4, 5];
let it = a.into_skipped(2);
assert_eq!(it.iter().collect::<Vec<_>>(), [&3, &4, &5]);
let it = it.into_skipped(1);
assert_eq!(it.iter().collect::<Vec<_>>(), [&4, &5]);
Sourcefn into_skipped_while<P>(self, skip_while: P) -> SkippedWhileCol<Self, Self, P>
fn into_skipped_while<P>(self, skip_while: P) -> SkippedWhileCol<Self, Self, P>
Consumes this collection and creates an iterable collection which is skipped-while version of this collection.
§Examples
use orx_iterable::*;
let a = [-1i32, 0, 1];
let it = a.into_skipped_while(|x| x.is_negative());
assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &1]);
Sourcefn into_stepped_by(self, step: usize) -> SteppedByCol<Self, Self>where
Self: Sized,
fn into_stepped_by(self, step: usize) -> SteppedByCol<Self, Self>where
Self: Sized,
Consumes this collection and creates an iterable collection which is stepped-by-step
version of this collection.
§Examples
use orx_iterable::*;
let a = [0, 1, 2, 3, 4, 5];
let it = a.into_stepped_by(2);
assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &2, &4]);
Sourcefn into_taken(self, n: usize) -> TakenCol<Self, Self>where
Self: Sized,
fn into_taken(self, n: usize) -> TakenCol<Self, Self>where
Self: Sized,
Consumes this collection and creates an iterable collection which is taken-n
version of this collection.
§Examples
use orx_iterable::*;
let a = [1, 2, 3, 4, 5];
let it = a.into_taken(3);
assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2, &3]);
let it = it.into_taken(2);
assert_eq!(it.iter().collect::<Vec<_>>(), [&1, &2]);
Sourcefn into_taken_while<P>(self, take_while: P) -> TakenWhileCol<Self, Self, P>
fn into_taken_while<P>(self, take_while: P) -> TakenWhileCol<Self, Self, P>
Consumes this collection and creates an iterable collection which is taken-while version of this collection.
§Examples
use orx_iterable::*;
let a = [-1i32, 0, 1];
let it = a.into_taken_while(|x| x.is_negative());
assert_eq!(it.iter().collect::<Vec<_>>(), [&-1]);
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.