Search code examples
rustfunctional-programming

How to refactor a loop with iterator. (Returning from closure)


I want to refactor a function and use an iterator rather than a for loop. I have exemplified the problem with the following demo code to be refactored:

fn with_loop() -> bool {
    let foo = [1, 2, 25, 4, 5];
    let mut sum = 0;
    for bar in foo {
        if bar > 20 {return false;}
        sum += bar;
    }
    sum > 10
}

I want to do something like the following, the problem is I cannot return from a closure of course.

fn functional_programming() -> bool {
    let foo = [1, 2, 25, 4, 5];
    let sum: i32 = foo
        .into_iter()
        .inspect(|bar_ptr| {
            if *bar_ptr > 20 {
                // functional_programming() returns false;
                print!("I want to return false");
            }
        })
        .sum();
    sum > 10
}

Some extra constraints which I would prefer not to negotiate:

  1. Scanning the iterable just once
  2. Avoid collecting and reopening the iterator
  3. Avoid too much nesting in the callbacks

Solution

  • "sum() can be used to sum any type implementing Sum, including Option and Result."

    fn functional_programming() -> bool {
        let foo = [1, 2, 25, 4, 5];
        let sum = foo
            .iter()
            .map(|i| if *i > 20 { Err(()) } else { Ok(*i) })
            .sum::<Result<i64, _>>();
        let Ok(sum) = sum else {
            return false;
        };
        sum > 10
    }
    
    

    Playground