# About the use of Iterator

``````    let mut count = 0;
for i in 2..100 {
for n in 2..(i + 1) {
if n == i {
println!("{}",n);
count += 1;
}
if i % n == 0 && n < i {
break;
}
}
}
println!("{}", count);
``````

This is a logic for calculating prime numbers and I don't know how to `break`, I see `break` handled in the `try_fold()` method but I don't seem to see it in the other methods, is it ok to use `try_fold()` here? Or is there a better way? Suppose I need to use `break` and `continue` several times, u even `break 'label` and `continue 'label`, is it not appropriate to use `Iterator`, instead I should use `for` loops?

What is wrong with using loops here in the first place? If you need to have the functionality of `break` and `continue` (which only work inside of loop bodies, not inside of callbacks you pass to the various iterator methods, as you've already stated in your question), why make this program harder to comprehend by using iterator methods instead of loop expressions?

While I do agree with @jofas about the for loops looking cleaner, it is still possible to do what you asked with iterators.

``````let mut count = 0;

// Iterate over i
(2..100)
.flat_map(|i| {
// Flatten with iterator over n
(2..i + 1).map(move |n| (i, n)).map_while(|(i, n)| {
// "break" once condition is met. We don't check for i == n yet
if i % n == 0 && n < i {
None
} else {
Some((i, n))
}
})
})
// Remove all items where n != i, yield n
.filter_map(|(i, n)| if n == i { Some(n) } else { None })
// Print each prime number and increment count
.for_each(|x| {
println!("{}", x);
count += 1;
});

println!("{}", count);
``````

Unlike your method, this one checks if `n == i` after it checks for `i % n == 0 && n < i`. It also uses `flat_map` to combine multiple `for` loops into one iterator. (Please see this post.)

If you need a more general solution for breaking out of iterators, please see `ControlFlow`, `try_for_each`, and `map_while`.

I hope this helps! Feel free to respond if you need anything else. (Iterators can be confusing )

3 Likes

Nice use of `Iterator`, doesn't look as badly as I thought.

Just nitpicks, but you could simplify this line:

to:

``````(2..=i).map_while(move |n| { ... }
``````

and move `i` into that closure instead of creating tuples of `(i, n)` first.

Also your `if` statements can be simplified with `bool::then_some`.

Then this line:

looks a bit cleaner IMO written as:

``````.filter_map(|(i, n)| (n == i).then_some(n))
``````

and

would become a one-liner (boolean logic must reversed though):

``````(i % n != 0 || n == i).then_some((i, n))
``````

Here a snippet with these changes:

1 Like

The mutation of external state in `for_each()` is also weird; it can also be removed using `count` and `inspect`.

5 Likes

This is beautiful declarative programming

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.