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,
&'i Self::Item: for<'i> 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,
<Self::Iterable<'b> as Iterable>::Iter: for<'b> 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
Ximplements [Collection<Item = T>], then&Ximplements [Iterable<Item = &T>]; - on the other hand, a type implementing
Iterablemay 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.
Examples found in repository?
More examples
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
fn main() {
let x = &Vector::new("x");
// good
let x0: Var = x[0];
assert_eq!(x0.to_string(), "x[0]");
// also good
let vars1: Vec<Var> = (0..1000).map(|i| x[i]).collect();
for (i, x) in vars1.iter().enumerate() {
assert_eq!(x.to_string(), format!("x[{}]", i));
}
// still good
let vars2: Vec<&Var> = (0..1000).map(|i| &x[i]).collect();
for (i, x) in vars2.iter().enumerate() {
assert_eq!(x.to_string(), format!("x[{}]", i));
}
}118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
fn main() {
let scope = Scope::default();
// instantiate some symbols
let x = scope.symbol("x");
let y = scope.symbol("y");
assert_eq!(&x.to_string(), "x");
assert_eq!(&y.to_string(), "y");
// apply binary operations to create new symbols
let p = x + y;
assert_eq!(&p.to_string(), "x + y");
let q = x - y;
assert_eq!(&q.to_string(), "x - y");
// and further binary operations
let t = p + q;
assert_eq!(&t.to_string(), "x + y + x - y");
// we only use 'scope' to create symbols
// but in the background, all expressions are collected in our scope
let all_expressions: Vec<_> = scope.expressions.iter().map(|x| x.to_string()).collect();
assert_eq!(
all_expressions,
["x", "y", "x + y", "x - y", "x + y + x - y"]
);
}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,
&'i Self::Item: for<'i> IntoIterator<Item = &'i <Self::Item as IntoIterator>::Item>,
fn into_flattened(self) -> FlattenedCol<Self, Self>where
Self: Sized,
Self::Item: IntoIterator,
&'i Self::Item: for<'i> 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.