Generic abstractions for combining and nesting reduction patterns for iterables.
The main entry point to this library is Reduce::reduce_with
, which can be called
on any Iterator
, and is very similar to Iterator::reduce
, but uses a generic
implementation of a Reductor
for the reduction logic.
The following examples shows some of the basic building blocks from which reductor
enables building more complex patterns:
```rust use reductor::{Reduce, Sum, Product, Count, Min, Max};
let iter = 0..10;
let Sum(sum) = iter.clone().reducewith::
let Max(max) = iter.clone().reducewith::
Notice that unlike Sum
and Product
, Min
and Max
won't reduce
an empty iterator into the default value. This mirrors the way Iterator::max
returns an Option<T>
, unlike Iterator::sum
.
Now, let's combine two Reductor
s to reduce an iterator that produces a pair of values:
```rust use reductor::{Reduce, Sum, Product};
let iter = 0..10;
let (Sum(sum), Product(product)) = iter
.clone()
.map(|x| (x, x * 2))
.reduce_with::<(Sum
asserteq!(sum, iter.clone().sum()); asserteq!(product, iter.map(|x| x * 2).product()); ```
Another abstraction provided by this library is ReductorPair
, which allows
reducing an iterator producing a single value by a pair of Reductor
s, in tandem.
```rust use reductor::{Reduce, ReductorPair, Sum, Max};
let iter = 0..10; let ReductorPair(Max(max), Sum(sum)) = iter .clone() .map(|x| x) .reduce_with::
asserteq!(sum, iter.clone().sum()); asserteq!(max, iter.clone().max().unwrap()); ```
These constructs allow building very complex iterator loops that compose numerous reductions into a single set of results.
```rust use reductor::{Reduce, ReductorPair, Count, Sum, Product, Max, Min};
let iter = (0i32..100).filtermap(|x| { if x % 2 == 0 { None } else { Some((x, x.leading_zeros())) } });
let ReductorPair(Count(count), (Sum(sum), ReductorPair(Min(min), Max(max)))) = iter .clone() .reduce_with::
asserteq!(count, iter.clone().count()); asserteq!(sum, iter.clone().map(|(x, ..)| x).sum()); asserteq!(min, iter.clone().map(|(.., x)| x).min().unwrap()); asserteq!(max, iter.map(|(.., x)| x).max().unwrap()); ```