rust使用vec在遍歷時刪除元素

2022-09-24 00:09:25 字數 3197 閱讀 9668

rust使用vec在遍歷時刪除元素

需求: 工作中有乙個地方需要用到在遍歷時把不符合條件的元素刪除掉,

比如乙個vec中是原始資料是vec![1,2,3,3,4,5],然後我要在遍歷中把等於c的元素刪除掉,目的是得到vec![1,2,4,5]

由於最開始只知道移除元素用remove方法,所以最開始是這樣寫的

let mut items:vec<&str> = vec!["a", "b", "c", "c", "d", "e"];

println!("before items is ", items);

for (index, item) in items.iter().enumerate()

}println!("then items is ", items);

但是報錯了,報錯提示為

error[e0502]: cannot borrow `items` as mutable because it is also borrowed as immutable

--> src/main.rs:8:13

|6 | for (index, item) in items.iter().enumerate() ", items);

let mut remove_indexs: vec= vec::new();

for (index, item) in items.iter().enumerate()

}println!("remove indexs is ", remove_indexs);

for i in remove_indexs

println!("then items is ", items);

列印出的結果是

before items is ["a", "b", "c", "c", "d", "e"]

remove indexs is [2, 3]

then items is ["a", "b", "c", "e"]

不報錯了,但是結果不對啊,預計是[「a」,"b","d","e"]的,怎麼變成了["a", "b", "c", "e"]了。

原因是:

第二個迴圈需要移除索引為2和3的兩個元素。所以有兩次迴圈:

上面方法失敗之後,覺得vec應該有處理這種情況的方法,所以看了原始碼,找到了答案。

vec有兩個方法可以實現我想要的。

vec.retain 和 vec.drain_filter

vec.retain 很簡單,retain的意思是保留,所以這個方法的意思就是接收乙個**函式,然後**函式裡面返回true進行保留,返回false的就移除。

示例:

let mut vec = vec![1, 2, 3, 4];

vec.retain(|&x| x % 2 == 0);

assert_eq!(vec, [2, 4]);

所以用vec.retain來實現的話,就是這樣

let mut items:vec<&str> = vec!["a", "b", "c", "c", "d", "e"];

println!("before items is ", items);

items.retain(|item| if *item == "c" else );

println!("then items is ", items);

drain的意思是排出的意思,所以這個函式就是排出過濾器,接收乙個**函式,然後把**函式裡面返回true的元素就會排出,自然也就從原本的vec裡面刪除掉了。然後有需要的話還可以蒐集排出的元素。

示例:

let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];

let evens = numbers.drain_filter(|x| *x % 2 == 0).collect::>();

let odds = numbers;

assert_eq!(evens, vec![2, 4, 6, 8, 14]);

assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);

所以用vec.drain_filter來實現的話,就是這樣

let mut items:vec<&str> = vec!["a", "b", "c", "c", "d", "e"];

println!("before items is ", items);

items.retain(|item| if *item == "c" else );

let removed_items = items.drain_filter(|item| if *item == "c" else ).collect::>();

println!("then items is ", items);

println!("removed item is ", removed_items);

error[e0658]: use of unstable library feature 'drain_filter': recently added

--> src/main.rs:7:31

|7 | let removed_items = items.drain_filter(|item| if *item == "c" else ).collect::>();

| ^^^^^^^^^^^^

| = note: see issue #43244 for more information

for more information about this error, try `rustc --explain e0658`.

這個函式是屬於不穩定的特性的,所以需要使用的話是有條件的

使用unstable feature的條件和步驟:

只有nightly才可以使用unstable

找到unstable feature的名字

感興趣的可以參考: 來啟用

STL容器遍歷時刪除元素

stl容器遍歷時在迴圈體內刪除元素最容易出錯了,根本原因都是因為迭代器有效性問題,在此記下通用刪除方法,該方法適用於所有含erase成員函式的序列容器 1 std vectormyvec 23 std vector iterator it myvec.begin 4while it myvec.en...

Java ArrayList遍歷時刪除乙個元素

我們知道arraylist的底層是用陣列實現的,如果你刪除了其中乙個元素,那麼後邊的元素都會向前移動。所以在遍歷時如果刪除元素,就要小心了。第一種方法,用陣列下標進行遍歷,如果需要刪除元素,我們從後向前遍歷,這樣不論有沒有元素刪除,我們都不會遺漏未被遍歷的元素。第二種方法,我們使用迭代器。itera...

Python 遍歷時刪除的處理 說明

遍歷時,建議不能直接進行remove刪除,會跳過某些元素 例項 a 1,2,3,4,5 for i in a a.remove i print a a 1,2,3,4,5 for i in a a.remove i print a 結果 2,4 remove 移除列表中某個值的第乙個匹配項 s 1,...