Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
725 views
in Technique[技术] by (71.8m points)

rust - Consume and replace elements in a vector with 1 or more elements

I'm trying to figure out an efficient Rust way of consuming elements of a vector and replacing them with one or more elements (of the same type) like in the non-compiling example:

fn main() {
    let mut myvec = vec![0, 1];
    println!("{:?}", myvec);
    
    for val in myvec.drain(..) {
        myvec.push(val+2);
        myvec.push(val+4);
    }
    println!("{:?}", myvec);
}

However, I am not even sure if Rust would even allow that as each operation needs a mutable reference (i.e. we need 2 mutable refs) but Rust can only allow one. Is there a way doing what I want to do or do I just need to have 2 separate vectors:

let mut myvec = vec![0, 1];
let mut newvec = Vec::new();
println!("{:?}", myvec);
    
for val in myvec.drain(..) {
    newvec.push(val+2);
    newvec.push(val+4);
}
println!("{:?}", newvec);

which outputs:

[0, 1]
[2, 4, 3, 5]

PS. I know that the splice method can achieve what I need but I also need a mutable reference inside the for loop.

question from:https://stackoverflow.com/questions/65843013/consume-and-replace-elements-in-a-vector-with-1-or-more-elements

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Since you are changing the size of the Vec, it's likely that it will need reallocation anyway. Additionally, you cannot mutate a Vec while you are iterating it (precisely because mutating it could cause it to reallocate). It won't be much different to collect into a new Vec:

myvec = myvec
    .drain(..)
    .flat_map(|val| iter::once(val + 2).chain(iter::once(val + 4)))
    .collect();

The chained iterator might not be as optimal as it could be. In nightly Rust, you could do:

#![feature(array_value_iter)]

use std::array;

myvec = myvec
    .drain(..)
    .flat_map(|val| array::IntoIter::new([val + 2, val + 4]))
    .collect();

Which should be more efficient.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...