1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
use crate::vector::{
    mapflat as mapreduce_vector,
    mapreduce as mapinject_vector,
    reduce as reduce_vector};

pub trait Reduces<R>: IntoIterator<Item=R>
    where R: IntoIterator
{
    fn reduce<F>(self, sequence: F) -> Option<R::Item> where
        Self: Sized,
        Self::IntoIter: Iterator<Item=R>,
        R::IntoIter: Iterator<Item=R::Item>,
        F: FnMut(R::Item, R::Item) -> R::Item,
    { reduce_vector(self.into_iter().flatten(), sequence) }

    fn mapflat<T, J, F>(self, indicator: J, sequence: F) -> Option<T> where
        Self: Sized,
        Self::IntoIter: Iterator<Item=R>,
        R::IntoIter: Iterator<Item=R::Item>,
        J: FnMut(R::Item) -> T,
        F: FnMut(T, R::Item) -> T,
    { mapreduce_vector(self.into_iter().flatten(), indicator, sequence) }

    fn mapreduce<T, J, F>(self, indicator: J, sequence: F) -> Option<T> where
        Self: Sized,
        Self::IntoIter: Iterator<Item=R>,
        R::IntoIter: Iterator<Item=R::Item>,
        J: FnMut(R::Item) -> T,
        F: FnMut(T, T) -> T,
    { mapinject_vector(self.into_iter().flatten(), indicator, sequence) }
}

impl<R, M> Reduces<R> for M where
    M: IntoIterator<Item=R>,
    R: IntoIterator
{}

pub fn reduce<R, M, F>(matrix: M, f: F) -> Option<R::Item> where
    M: IntoIterator<Item=R>,
    R: IntoIterator,
    M::IntoIter: Iterator<Item=R>,
    R::IntoIter: Iterator<Item=R::Item>,
    F: FnMut(R::Item, R::Item) -> R::Item,
{ reduce_vector(matrix.into_iter().flatten(), f) }

pub fn mapflat<R, M, T, J, F>(matrix: M, indicator: J, sequence: F) -> Option<T> where
    M: IntoIterator<Item=R>,
    R: IntoIterator,
    M::IntoIter: Iterator<Item=R>,
    R::IntoIter: Iterator<Item=R::Item>,
    J: FnMut(R::Item) -> T,
    F: FnMut(T, R::Item) -> T,
{ mapreduce_vector(matrix.into_iter().flatten(), indicator, sequence) }

pub fn mapreduce<R, M, T, J, F>(matrix: M, indicator: J, sequence: F) -> Option<T> where
    M: IntoIterator<Item=R>,
    R: IntoIterator,
    M::IntoIter: Iterator<Item=R>,
    R::IntoIter: Iterator<Item=R::Item>,
    J: FnMut(R::Item) -> T,
    F: FnMut(T, T) -> T,
{ mapinject_vector(matrix.into_iter().flatten(), indicator, sequence) }

#[cfg(test)]
mod tests {
    use std::cmp::max;

    use super::*;

    #[test]
    fn test_reduce() {
        let sample = vec![
            vec![4, 2, 7],
            vec![7, 5, 9],
            vec![3, 0, 4]
        ];
        let result = sample.reduce(|a, b| max(a, b));
        println!("{}", result.unwrap());
    }
}