隱私權政策

搜尋此網誌

技術提供:Blogger.

關於我自己

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

2023年11月13日 星期一

Rust 切片sort和sort_by概述 - 將資料排序


這篇講將數據排序

目前有兩個我比較常用的方法

一個是sort,另一個是sort_by

差別在一個快速一個,可以自定義排序方法


sort與sort_by

文件[1]這樣解釋sort

    pub fn sort(&mut self)

而sort_by的文件[2]則是

    pub fn sort_by<F>(&mut self, compare: F)
    where
        F: FnMut(&T, &T) -> Ordering,

可看出sort直接默認排序

而sort_by則是要放入一個FnMut,也就是一個閉包,最後直接輸出排序


例子

以結果來說,sort提供簡潔方便的做法,不必額外輸入參數

而sort_by則是更靈活,可以根據使用者的需求彈性變動

舉個例子,如果想要將一個數組從小到大排列可以這樣打

    // 使用 sort
    let mut numbers = [4, 2, 8, 1, 6];
    numbers.sort();
    println!("{:?}", numbers);
[1, 2, 4, 6, 8]

直接使用numbers.sort()就好

而如果使用sort_by就要這樣打

    // 使用 sort_by
    let mut numbers = [4, 2, 8, 1, 6];
    numbers.sort_by(|a, b| a.cmp(b));
    println!("{:?}", numbers);
[1, 2, 4, 6, 8]

sort_by需要使用閉包,閉包為兩個參數

比較兩個參數的大小,並回傳排序後的值

如果想要反向排序可以改成b.cmp(a)

    // 使用 sort_by
    let mut numbers = [4, 2, 8, 1, 6];
    numbers.sort_by(|a, b| b.cmp(a));
    println!("{:?}", numbers);
[8, 6, 4, 2, 1]


差別

而有些事情是只有sort_by可以做到

例如我們擁有一個含名字與年紀的struct

希望照著年齡排

則需要透過sort_by

use std::io;
#[derive(Debug)]
struct Person {
    name: String,
    age: u32,
}
fn main() {
    let mut people = vec![
        Person {
            name: "Alice".to_string(),
            age: 30,
        },
        Person {
            name: "Bob".to_string(),
            age: 25,
        },
        Person {
            name: "Charlie".to_string(),
            age: 35,
        },
    ];
    // 年紀由小至大
    people.sort_by(|a, b| a.age.cmp(&b.age));
    println!("{:?}", people);
}

[Person { name: "Bob", age: 25 }, Person { name: "Alice", age: 30 },
Person { name: "Charlie", age: 35 }]


需要自定義排序的方法都可以使用sort_by

再舉個例子

假設想要根據字串長度排序

如果使用sort,他會根據第一個字母排序

    let mut words = ["apple", "banana", "cherry", "date", "elderberry"];
    words.sort();
    println!("{:?}", words);
["apple", "banana", "cherry", "date", "elderberry"]


但如果使用sort_by,則可以

    let mut words = ["apple", "banana", "cherry", "date", "elderberry"];
    words.sort_by(|a, b| a.len().cmp(&b.len()));
    println!("{:?}", words);
["date", "apple", "banana", "cherry", "elderberry"]


sort_by可以應用的範圍比較廣

而sort則是方便快速

但兩種方法的時間複雜度最糟糕情況下都是O(n * log(n)) [1][2]

要注意這個方法所花費的時間


參考資料

[1] https://doc.rust-lang.org/std/primitive.slice.html#method.sort

[2] https://doc.rust-lang.org/std/primitive.slice.html#method.sort_by

0 comments:

張貼留言