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.
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);
}
5 Likes
dbdr
May 6, 2020, 3:03pm
3
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.
6 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.
L.F
May 7, 2020, 9:24am
6
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);
(playground )
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[1];
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[1]);
system
Closed
August 5, 2020, 11:53am
8
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.