What is a stable way to iterate over a range with a custom step?

How do I go if I want to iterate with a custom step in stable Rust? Essentially something like C / C ++

for (int i = 0; i < n; i += 2) { } 

I have already tried using range_step_inclusive and solutions in How to iterate over a range using a custom step? :

 use std::iter::range_step_inclusive; for i in range_step_inclusive(0, n, 2) { println!("i: {}", i); } 

But it looks like it is not available in Rust 1.1:

 error: unresolved import `std::iter::range_step_inclusive`. There is no `range_step_inclusive` in `std::iter` 

What would be an alternative? Perhaps an idiomatic way to create custom ranges.

+7
iterator rust
source share
5 answers

As of Rust 1.1

You can always write this old fashionedly:

 fn main() { let mut i = 0; while i < 100 { println!("i: {}", i); i += 2; } } 

What can then be abstracted:

 use std::ops::Add; fn step_by<T, F>(start: T, end_exclusive: T, step: T, mut body: F) where T: Add<Output = T> + PartialOrd + Copy, F: FnMut(T) { let mut i = start; while i < end_exclusive { body(i); i = i + step; } } fn main() { step_by(0, 100, 2, |i| { println!("i: {}", i); }) } 

An interesting historical note, I believe that initially the whole cycle was done with a closure like this before iterators became extremely common.

+4
source share

There is a way to use let "redefinition":

 for i in 0..((n + 1) / 2) { let i = i * 2; // … } 

Or use Iterator::map :

 for i in (0..((n + 1) / 2)).map(|i| i * 2) { // … } 
+5
source share

I think I will stick with the while loop. But if you really need an iterator based method, you can try this

 fn main(){ let (start, step, end) = (1, 2, 20); for i in (0..).map(|x| start+step*x) .take_while(|&x| x<end){ println!("{:?}", i); } } 
+3
source share

Use the num box

Cargo.toml:

 [dependencies.num] version = "0.1.25" default-features = false 

Since you only need the basics of the box, use default-features = false .

Rust:

 extern crate num; use num::range_step; for i in range_step(0, 10, 2) { /* */ } 

range_step is common to whole types of rust.

+3
source share

You can use the iterator_step_by function.

Here is an example of two threads, one of which prints odd numbers and the other even:

 #![feature(iterator_step_by)] extern crate thebook; use std::thread; use std::time::Duration; fn main() { let handle = thread::spawn(|| { for i in (1..1000).step_by(2) { println!("{}", i); } }); for i in (2..1000).step_by(2) { println!("{}", i); } handle.join(); } 

Without this function, you can also use a filter in the range:

 use std::thread; use std::time::Duration; fn main() { let handle = thread::spawn(|| { for i in (1..1000).filter(|x| x % 2 != 0) { println!("{}", i); } }); for i in (2..1000).filter(|x| x % 2 == 0) { println!("{}", i); } handle.join(); } 
-one
source share

All Articles