9

In the C family of languages, I can do this on one line:

for(int i = lo, int j = mid+1; i <= mid && j <= hi; i++, j++){
    ...
}

But in Rust... I can only write it like this:

for i in lo..mid+1 {
    let mut j = mid+1;
    if j <= hi {
        break;
    }
    ...
    j += 1;
}

Is there's a more efficient way to implement this?


Using an iterator works for above, but using an iterator makes some occasions like using arithmetic troublesome, such as

for (int i = 0; i < n; i ++) {
    if (a[i] == ...) {
        i += 5;
    }
}

In Rust, this does not work. The variable i will not be incremented by 5, but by 1 instead:

for i in 0..n {
    if a[i] == ... {
        i += 5;
    }
} 
1
  • Thank you~ It works. Rust's for loop uses the iterator which makes some occasions like using arithmetic be a little troublesome. Just as for (int i = 0; i < n; i ++) if (a[i] == ...) i += 5;. In rust it uses iterator so that for i in 0..n{ if a[i] == ... { i+=5; }} not worked. The variable i will not add 5 next turns, but add 1 instead... Commented Apr 9, 2017 at 4:15

1 Answer 1

10

You can create two parallel range iterators, zip them, then iterate though the combination:

fn main() {
    let values = [10, 20, 30, 40, 50, 60, 70, 80, 90];
    let lo = 2;
    let mid = 5;
    let hi = 7;

    let early_indexes = lo..(mid + 1);
    let late_indexes = (mid + 1)..(hi + 1);
    for (i, j) in early_indexes.zip(late_indexes) {
        println!("{}, {}", i, j);
        println!("{} - {}", values[i], values[j]);
    }
}

Someday, inclusive ranges will be stabilized, and you should be able to something like this (depending on the eventual syntax):

let early_indexes = lo...mid;
let late_indexes = (mid + 1)...hi;
for (i, j) in early_indexes.zip(late_indexes) {
    println!("{}, {}", i, j);
    println!("{} - {}", values[i], values[j]);
}

If you are actually iterating though a slice as I've shown for my example, you can also just combine the two iterators directly and ignore the index:

let early_values = values[lo..(mid + 1)].iter();
let late_values = values[(mid + 1)..(hi + 1)].iter();
for (i, j) in early_values.zip(late_values) {
    println!("{}, {}", i, j);
}

The variable i will not be incremented by 5, but by 1 instead.

Yes, incrementing by a step is annoying, and some day it will also be stabilized. In the meantime:

If you need full control, you can always use while or loop:

let mut i = 0;
while i < n {
    if a[i] == ... {
        i += 5;
    }

    i += 1;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the detailed explanation that solves my problem! ~

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.