Nested for loops but with iterators?

I'm doing an exercise from exercism.io where I need to calculate the sum of the multiples of some numbers below a limit.

I tried the code below. Basically what I'm trying to do would be like a for loop within a for loop but with iterators:

pub fn sum_of_multiples(limit: u32, factors: &[u32]) -> u32 {
    factors.iter()
    .map(|x| {
        (1..).take_while(|f| f * x < limit).sum()
    })
    .sum()
}

but I get the following error:

error[E0282]: type annotations needed
 --> src/lib.rs:3:6
  |
3 |     .map(|x| {
  |      ^^^ cannot infer type for `B`

Can anyone explain what's the problem? Maybe there's another obvious way to do what I'm trying to do, but I'm oblivious to it. I'm just beginning to step into this whole functional programming thing.

This is what I would do in C:

uint32_t sum_of_multiples(uint32_t limit, uint32_t * factors) {
    uint32_t sum = 0;
    for (uint32_t i = 0; i < factors.len(); i++) {
        for (uint32_t j = 1; true; j++) {
            if (factors[i] * j < limit) {
                sum += factors[i] * j;
            }
            else {
                break;
            }
        }
    }
    return sum;
}

Rust can't infer the resulting type of the map call, because you could Sum a u32 into many different types. Adding the relevant annotation (-> u32) fixes it.

pub fn sum_of_multiples(limit: u32, factors: &[u32]) -> u32 {
    factors.iter()
    .map(|&x| -> u32 {
        (1..).take_while(|f| f * x < limit).sum()
    })
    .sum()
}
2 Likes

Aha! Thanks :slight_smile:

Another option is a turbofish -- sum::<u32>()

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.