Search code examples
rustvector

How to push additional element to Vec<&Vec<String>>?


I am trying to accomplish something rather simple, but not sure how to do it in Rust.

I have a Vec<&Vec>, something like the below example.

[
 ["a1", "b2", "c3"],
 ["d1", "e2", "f3"],
 ["g1", "h2", "i3"]
]

I want to push an additional string at the end of each vector.

[
 ["a1", "b2", "c3", "something"],
 ["d1", "e2", "f3", "something"],
 ["g1", "h2", "i3", "something"]
]

What I've tried so far is below:

vec_of_strings
    .iter_mut()
    .map(|x| x.clone().push("something".to_string()))
    .collect::<Vec<_>>();

println!("{:?}", vec_of_strings);

But the output is showing that nothing is appended.


Solution

  • What you're doing creates a new Vec, it does not modify the exist ones. Indeed, the existing ones cannot be modified as you are borrowing them immutably (the & in Vec<&Vec<_>>).

    Note that using .iter_mut() instead of .iter() is pointless here as you aren't mutating the elements.

    Additionally, Vec::push() doesn't return anything, so the .to_string() invocation should be giving you a compile-time error. (I assume you meant to call this on the string literal instead.)

    Fixing the above issues:

    let new_vec_of_strings = vec_of_strings
      .iter()
      .map(|x| {
        let mut x = x.clone();
        x.push("something".to_string());
        x
      })
      .collect::<Vec<_>>();
    
    println!("{:?}", new_vec_of_strings);
    

    However, this all seems like an XY problem -- there is probably a better way to accomplish whatever your goal is.