itertools icon indicating copy to clipboard operation
itertools copied to clipboard

Map with cache

Open malthe opened this issue 3 years ago • 2 comments

I have found it useful to have a map that is able to hold a cached value, which can be used during the iteration.

The name fold_map comes to mind because it can be implemented using fold but works like a map.

In the example below, a vector of booleans is mapped such that values around a true value are also true.

let v = vec![true, false, false, false, true, false, true];
let i = v.into_iter().enumerate().circular_tuple_windows().fold_map(None, |prev, (curr, next)| {
    let result = curr.1 || (next.0 > curr.0 && next.1) || if let Some(prev) = prev {
        (prev.0 < curr.0 && prev.1) || 
    } else { 
        false
    };
    (curr, result)
}); 

This would yield an iterator for [true, true, false, true, true, true, true].

And a smaller, somewhat random example:

let v = vec![1, 2, 3, 4];
let i = v.iter().fold_map(None, |p, n| (Some(n), n + p.unwrap_or(0))) 

This would yield an iterator for [1, 3, 5, 7].

malthe avatar Jul 07 '22 21:07 malthe

If you need a map with some internal state, maybe you want https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.scan ?

scottmcm avatar Jul 08 '22 06:07 scottmcm

@scottmcm scan returns that internal state as the result – what I am looking for is to still return the result of the map so to speak (and simply discarding the internal state after iteration completes).

malthe avatar Jul 08 '22 07:07 malthe