# Finding and removing an element in a vec

Hello, I want to do find an element in a vec and remove it.

Here is how I do it.

``````let mut some_vec = vec![0, 10, 20, 30];
if let Some(index) = some_vec.iter().find(|value| **value == 10) {
some_vec.swap_remove(*index);
}
``````

However, I get this warning

``````warning: cannot borrow `some_vec` as mutable because it is also borrowed as immutable
``````

I skim throught https://github.com/rust-lang/rust/issues/59159 and decided to try the following, but I still get the same warning.

``````let mut some_vec = vec![0, 10, 20, 30];
let index = some_vec.iter().find(|value| **value == 10).clone();
if let Some(index) = index {
some_vec.swap_remove(*index);
}
``````

So, I'm a bit confused. In the later, I tought that it would be fine since I'm using clone. How could I get rid of this warning?

You can find a playground with both approaches.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6a04a05b3c2b89f2a66e50a2e139025b

1 Like

Instead of `find`, which returns a reference to the matching value, I think you want `position`, which returns the index of the matching value:

``````if let Some(index) = some_vec.iter().position(|value| *value == 10) {
some_vec.swap_remove(index);
}
``````
4 Likes

One simple way to do it is to retain all elements that don't have that value:

``````    let mut some_vec = vec![0, 10, 20, 30];
some_vec.retain(|value| *value != 10);
``````

Note that in case there are several elements with value 10, this will remove all of them, which might or might not be what you want.

5 Likes

While I think the answer about `find` vs. `position` is correct for your intention, I thought I'd address this:

Cloning an `Option<&T>` gets you another `Option<&T>`, with the same borrowed lifetime. Instead, you can use `.cloned()` to get an independent `Option<T>`.

Another possibility for `Copy` types is to destructure the reference when you match it:

``````if let Some(&index) = index { ... }
``````
3 Likes

That is exactly what I wanted. I was confused. Thanks.

There is also a nightly method to achieve directly what you want — `remove_item`: (requires `#![feature(vec_remove_item)]`)

``````let mut some_vec = vec![0, 10, 20, 30];
some_vec.remove_item(&10);
``````
1 Like

That method is unlikely to be stabilized, because it can't work for a common case of:

``````let mut some_vec = vec![0, 10, 20, 30];
let some_item = &vec;
some_vec.remove_item(some_item);
``````

and it's actually behaving like `remove_first_item`:

``````let mut some_vec = vec![0, 10, 10, 10];
some_vec.remove_item(&10);
assert_eq!(10, vec);
``````

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.