# Clone Vector in rust except at one index [closed]

Let's consider you want to clone all items of a vector orig except the item of index i should be taken from alternative value alt.

Lets say the items are of the type

struct Bla{
// Some fields
}


## Using for loop

On simple solution would be:

fn clone(orig: &Vec<Bla>, i: usize, alt: Bla) -> Vec<Bla> {
let cloned = Vec::new();
for (j, item) in orig.iter().enumerate() {
let new_item = if i != j {item.clone()} else {alt};
cloned.push(new_item);
}

cloned
}


Note: Does not compile, because the compiler does not know that i==j is only valid once.

## Using functional style

The functional alternative would be the follow:

fn clone(orig: &Vec<Bla>, i: usize, alt: Bla) -> Vec<Bla> {
orig.iter().enumerate()
.map(|(j, item)| if i != j {item.clone()} else {alt})
.collect::<Vec<Bla>>()
}


The last one looks nice, but does not compile :( because the rust compiler does not know that alt gets moved (or consumed) only once (i==j).

## Using mem replace

In order to fix the version above one can use a default value for the index which should be replaced.

fn clone(orig: &Vec<Bla>, i: usize, alt: Bla) -> Vec<Bla> {
let mut result = orig.iter().enumerate()
.map(|(j, item)| if i != j {item.clone()} else {Bla::default()})
.collect::<Vec<Bla>>();

mem::replace(&mut result[i], alt);
result
}


What is the most concise and fastest implementation to do so?

## closed as off-topic by Toby Speight, Grajdeanu Alex., Graipher, pacmaninbw, Austin HastingsApr 16 at 22:07

This question appears to be off-topic. The users who voted to close gave this specific reason:

• "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Toby Speight, Grajdeanu Alex., Graipher, pacmaninbw, Austin Hastings
If this question can be reworded to fit the rules in the help center, please edit the question.

In my opinion none of your solution is idiomatic and all use an useless comparaison.

Using for loop:

• Doesn't pre-allocate the vector
• Use a comparaison that could be avoid

Using functional style:

• Use a comparaison that could be avoid

Using mem replace:

• Use a comparaison that could be avoid
• Is unnecessary complex to just copy a vector

Also, you should avoid take a &Vec<T> as parameter, it's much better to take a &[T]. See: Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?

I would use one of the following version:

#[derive(Clone)]
struct Pokemon {
}

fn a(pokemons: &[Pokemon], i: usize, pokemon: Pokemon) -> Vec<Pokemon> {
let mut digimons = Vec::with_capacity(pokemons.len());

digimons.extend_from_slice(&pokemons[0..i]);
digimons.push(pokemon);
digimons.extend_from_slice(&pokemons[i + 1..]);

digimons
}

fn b(pokemons: &[Pokemon], i: usize, pokemon: Pokemon) -> Vec<Pokemon> {
let mut digimons = pokemons.to_vec();
digimons[i] = pokemon;

digimons
}

fn c(pokemons: &[Pokemon], i: usize, pokemon: Pokemon) -> Vec<Pokemon> {
pokemons[0..i]
.iter()
.cloned()
.chain(std::iter::once(pokemon))
.chain(pokemons[i + 1..].iter().cloned())
.collect()
}


I don't really know witch version is better, a() and c() should be the same but sometime chain() is not optimized away. And b() is probably the most straightforward solution. I think I would choice a() in a production code.

However, looking at the assembly, we can see that a() and c() doesn't produce the same, and that b() is the simplest.

• But solution a() and c() avoid copying/cloning ith element unnecessary from the incomming slice. – Matthias Apr 12 at 14:51
• @Matthias depend on the cost of clone, b() "could" be faster. If you really want to be sure, you must do some bench-marking. – Stargateur Apr 12 at 16:19