MJ49
MJ49

Reputation: 123

How to create a Vector of Vectors within a For-Loop?

I'm trying to create a vector of vectors using for-loops. I'm tried the design below but to no success:

// num_partitions is the primary vector, v is vector that contains a set of integers
// This function should return a Primary Vector that hold num_partitions of vectors

fn partition_data(num_partitions: usize, v: &Vec<usize>) -> Vec<Vec<usize>> {
    let partition_size = v.len() / num_partitions;

    // Create a vector that will contain vectors of integers
    let mut xs: Vec<Vec<usize>> = Vec::new();
 
    for j in 0..partition_size {
        for i in 0..partition_size {
            // create a new Vector and push elements to it
            let mut x1: Vec<usize> = Vec::new();
            x1.push(v[i]);
        }
        // push this new Vector the the Primary Vector
        xs.push(x1);
    }
   
    // return primary vector
    xs
}

Upvotes: 1

Views: 1592

Answers (2)

Ibraheem Ahmed
Ibraheem Ahmed

Reputation: 13518

Here is a simplified example of your problem:

let mut outer_vec: Vec<Vec<usize>> = Vec::new();
for j in 0..5 {
  for i in 0..5 {     
    let mut inner_vec: Vec<usize> = Vec::new();
    inner_vec.push(1);
  }
  outer_vec.push(inner_vec);
}

inner_vec is declared in the inner for loop. outer_vec is declared in the outer for loop. Due to Rust's scoping and ownership rules, inner_vec is destroyed at the end of it's scope (the inner for loop), and therefore the outer scope (the outer for loop) cannot access it:

for i in 0..5 {
  let mut inner_vec: Vec<usize> = Vec::new();
  // inner_vec is valid from here ^
  inner_vec.push(1);
  // inner_vec is destroyed here, it's memory is freed
}
// inner_vec is now non-existent, so this fails:
outer_vec.push(inner_vec);

To fix this, you can declare inner_vec in the outer scope:

let mut inner_vec: Vec<usize> = Vec::new();
for i in 0..5 {
  inner_vec.push(1);
}
// inner_vec and outer_vec are now in the same scope, so this is fine:
outer_vec.push(inner_vec);

Upvotes: 1

pretzelhammer
pretzelhammer

Reputation: 15105

There are handy functions in the Rust standard library that already do most of what you need to implement this function easily using just Iterators:

fn partition_data(num_partitions: usize, v: &Vec<usize>) -> Vec<Vec<usize>> {
    let partition_size = v.len() / num_partitions;
    v.chunks(partition_size)
        .map(|chunk| chunk.to_vec())
        .collect()
}

playground

Upvotes: 3

Related Questions