rust使用vec在遍歷時刪除元素
需求: 工作中有乙個地方需要用到在遍歷時把不符合條件的元素刪除掉,
比如乙個vec中是原始資料是由於最開始只知道移除元素用remove方法,所以最開始是這樣寫的vec![1,2,3,3,4,5]
,然後我要在遍歷中把等於c的元素刪除掉,目的是得到vec![1,2,4,5]
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,...