Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop over 0 .. v.len() - 1 when v might be empty?

What's the correct way to loop over 0 .. v.len() - 1 when the vector v might be empty?

Consider the following code, which prints all choices of 2 elements in a vector [5, 6, 7]:

fn main() {
  let v: Vec<i32> = vec![5, 6, 7];
  for i in 0 .. v.len() - 1 {
    for j in i + 1 .. v.len() {
      println!("{} {}", v[i], v[j]);
    }
  }
}

It prints

5 6
5 7
6 7

as expected.

Now, if we instead have

let v: Vec<i32> = vec![];

then the program panics due to overflow, which is also expected.

Q: How to fix it without changing the structure and the logic of the program, and without involving signed integers?

The following are some examples of the workarounds that I don't want:

  • Handling empty v separately (changes the logic). Overall, I don't want any checks that v is empty, e.g. by if v.len() == 0 { 0 } else { v.len() - 1 }

  • Changing the order of loops (changes the logic and the output):

    for j in 0 .. v.len() {
        for i in 0 .. j {
    
  • Shifting the indices (changes the logic):

    for i in 1 .. v.len() {
        for j in i .. v.len() {
            // Now i is shifted by 1
    
  • Using i32 (casts):

    for i in 0 .. v.len() as i32 - 1 {
        for j in i + 1 .. v.len() as i32 {
            // cast i and j to usize
    

Overall, I hope that there is a clean way to handle 0 .. v.len() - 1 without any hacks.

like image 907
Dmitry Avatar asked Sep 05 '25 00:09

Dmitry


1 Answers

Notice that, if i == v.len()-1, nothing happens in the body of the outer loop, because i+1..v.len() is an empty iterator. Therefore, the simplest way to avoid integer underflows is simply to remove the -1:

fn main() {
  let v: Vec<i32> = vec![5, 6, 7];
  for i in 0 .. v.len() {
    for j in i + 1 .. v.len() {
      println!("{} {}", v[i], v[j]);
    }
  }
}

produces

5 6
5 7
6 7

and if I replace v with Vec::new(), you get no output, as expected.

like image 92
BlackBeans Avatar answered Sep 07 '25 21:09

BlackBeans