Rust - 迭代filter_map概述 - 同時過濾與處理數據
filter_map
位於iter
同時具有兩種特性
可以過濾資料也可以處理數據
文件這樣解釋filter_map[3]
創建一個迭代器具有filter和map的特色
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where
Self: Sized,
F: FnMut(Self::Item) -> Option<B>,
self為迭代器
需要輸入一個閉包FnMut,回傳Option
最後回傳一個迭代器
舉一個例子
假設有一個數組
我只想要得到偶數,並且要獲得該值平方
需要這樣打
let numbers = vec![1, 2, 3, 4, 5];
let result: Vec<i32> = numbers
.into_iter()
.filter(|x| x % 2 == 0)
.map(|x| x * x)
.collect();
println!("{:?}", result);
}
[4, 16]
第一行創立數組
第三行將其放入至迭代器
第四行透過filter先抓出偶數
第五行將filter結果平方
最後collect
但如果透過filter_map可以改成這樣打
let numbers = vec![1, 2, 3, 4, 5];
let result: Vec<i32> = numbers
.into_iter()
.filter_map(|x| if x % 2 == 0 {
Some(x * x)
} else {
None
})
.collect();
println!("{:?}", result);
[4, 16]
改成filter_map,並使用閉包
將偶數取出(x % 2 == 0)
回傳Some(x平方值)
否則回傳None
再舉一個文件中的例子
假設要判斷數組是不是合格的數字
使用filter_map可以這樣簡化
let a = ["1", "two", "NaN", "four", "5"];
let mut iter = a.iter()
.filter_map(|s| s.parse().ok());
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
直接使用parse判斷是不是整數並直接輸出
但如果是filter + map則會比較麻煩
let a = ["1", "two", "NaN", "four", "5"];
let mut iter = a
.iter()
.map(|s| s.parse())
.filter(|s| s.is_ok())
.map(|s| s.unwrap());
assert_eq!(iter.next(), Some(1));
assert_eq!(iter.next(), Some(5));
assert_eq!(iter.next(), None);
要先使用map判斷元素
然後使用filter把非數值過濾
最後在使用map unwrap
整體會比較多程式碼
參考資料
[1] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter
[2] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map
[3] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter_map
0 comments:
張貼留言