隱私權政策

搜尋此網誌

技術提供:Blogger.

關於我自己

我的相片
目前從事軟體相關行業,喜歡閱讀、健身、喝調酒。習慣把遇到的問題記下來,每天做一些整理方便自己以後查。 Python、Rust、Kotlin等程式語言皆為自學,目前比較著重在Rust語言,歡迎一起討論。

2023年10月26日 星期四

Rust 迭代filter概述 - 用於過濾資料


最近寫Rust用到迭代的次數比較多

把整個用法心得寫下來讓大家也可以學


這篇先講filter

filter主要用於過濾資料

文件[1]這樣表示

    fn filter<P>(self, predicate: P) -> Filter<Self, P>
    where
        Self: Sized,
        P: FnMut(&Self::Item) -> bool,

self為一個迭代器

透過閉包找出符合得值

當不符合條件則為false會把資料過濾掉

最後回傳一個迭代器


舉一個例子來說

假設我有一變數num,為1, 2, 3, 4, 5, 6

把奇數過濾掉,只想要留下偶數

最快的方法就是使用filter

filter用法通常搭配閉包

閉包內的值為true才會存取值

    let num: Vec<_> = vec![1, 2, 3, 4, 5, 6];
    let res: Vec<_> = num.into_iter().filter(|x| x % 2 == 0).collect();
    assert_eq!(vec![2, 4, 6], res);

上述程式一行一行分析

第一行會創建一Vec數組

第二行為num.into_iter().filter(|x| x % 2 == 0).collect();

into_iter: 表示將數組轉化為迭代器,類似for迴圈[2]

filter(|x| x%2):設變數x,並對迭代器中所有數值取二餘數,若為偶數則不過濾[3]

collect:將過濾完成後的存進Vec

最後比較結果


若使用for迴圈則需要這樣寫

    let num: Vec<_> = vec![1, 2, 3, 4, 5, 6];
    let mut res: Vec<_> = Vec::new();
    for x in num {
        if x % 2 == 0 {
            res.push(x);
        }
    }
    assert_eq!(vec![2, 4, 6], res);

但軟體工程師總是會希望自己程式帥一點

一行解決的程式 帥!

大致上了解filter的用法後下方有一個比較難的題目

來自於Code war,並附上中英文給大家

Return the number (count) of vowels in the given string.

We will consider a, e, i, o, u as vowels for this Kata (but not y).

The input string will only consist of lower case letters and/or spaces.

根據給予的String,回傳母音總個數
母音包括a、e、i、o、u,不包括y
給予的String僅包含小寫英文以及空格

題目呼叫get_count,傳入&str,&str為一長字串切片
fn get_count(string: &str) -> usize {
    // TODO
}

最後輸出usize表示個數

當然程式有很多種打出來的方法

但可以想想看怎麼用filter去做

下方有答案可以先不要看

解答思路

fn get_count(string: &str) -> usize {
    string
    .chars()
    .filter(|num| num == &'a' || num == &'e' || num == &'i' || num == &'o' || num == &'u')
    .collect::<Vec<_>>()
    .len();
}

將輸入string轉成char

並使用filter判斷其數值是不是a, e, i, o, u

轉後轉成一個Vec數組並判斷其長度


但其實也可以再更簡化一點,使用contains打的字會少一點

    string
        .chars()
        .filter(|num| ['a', 'e', 'i', 'o', 'u'].contains(num))
        .count();

之後會再找時間,把map、fold、chain稍微講解一下


參考資料

[1] https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.filter

0 comments:

張貼留言