1

I have the following nested for loop in Rust:

#[derive(Debug)]
struct Tes2 {
    a: Vec<String>,
    b: Vec<Vec<String>>,
}

fn vectes() {
    let mut ff: Vec<Tes2> = Vec::new();

    let one = vec![
        vec!["a".to_string(), "b".to_string()],
        vec!["x".to_string(), "y".to_string()],
    ];

    let two = vec![
        vec![
            vec!["d".to_string(), "e".to_string()],
            vec!["g".to_string(), "h".to_string()],
            vec!["j".to_string(), "k".to_string()],
        ],
        vec![
            vec!["mm".to_string(), "nn".to_string()],
            vec!["oo".to_string(), "pq".to_string()],
            vec!["rr".to_string(), "ss".to_string()],
        ],
    ];

    for i in one {
        for (mut k, j) in two.clone().into_iter().enumerate() {
            if k != 1 {
                ff.push(Tes2 { a: i.clone(), b: j });
            }
            k += 1;
        }
    }
    println!("{:?}", ff);
}

The output of which is:

[Tes2 { a: ["a", "b"], b: [["d", "e"], ["g", "h"], ["j", "k"]] }, Tes2 { a: ["x", "y"], b: [["d", "e"], ["g", "h"], ["j", "k"]] }]

This is what I want and is correct. Essentially, in each new struct I am trying to pair one[0] with two[0] and then one[1] with two[1] etc.

I am sure there is a much more real and efficient "Rust way" to do this, maybe with the map method, and avoiding for loops altogether, but I have tried in different ways and it never worked.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
Jason Jurotich
  • 441
  • 4
  • 24

1 Answers1

2

The method you're looking for is Iterator::zip() (or since Rust 1.59.0, std::iter::zip()).

for (a, b) in std::iter::zip(one, two) {
    ff.push(Tes2 { a, b })
}

Playground.

At that time, you can avoid using a loop altogether and just use collect():

let ff: Vec<_> = std::iter::zip(one, two)
    .map(|(a, b)| Tes2 { a, b })
    .collect();

Playground.

Of course, a simple loop will always work:

for i in 0..one.len() {
    ff.push(Tes2 {
        a: one[i].clone(),
        b: two[i].clone(),
    });
}

Playground.

As a side note, it's better to use .iter().clone() than .clone().into_iter(). See How to determine whether to use .clone() and .cloned() with iterators.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77