如何按 2 个或多个字段对结构体 Vec 进行排序?

Gun*_*t.r 10 rust

example

struct MyStruct{
    row: u8,
    column: u8
}

let my_vector = a Vec<MyStruct> with like 100 items in it
Run Code Online (Sandbox Code Playgroud)

可以说我有一个像这样的简单设置^。我想my_vector按行然后按列对 100 个项目的列表进行排序,这样我的向量就会看起来像sample 1而不是sample 2.

sample 1

my_vector = vec![
MyStruct { row: 10, column: 1 },
MyStruct { row: 10, column: 2 },
MyStruct { row: 10, column: 3 }, ]
Run Code Online (Sandbox Code Playgroud)

sample 2

my_vector = vec![
MyStruct { row: 10, column: 3 },
MyStruct { row: 10, column: 1 },
MyStruct { row: 10, column: 2 }, ]
Run Code Online (Sandbox Code Playgroud)

目前,我一直在写这篇文章,描述如何使用该sort_by_key()函数按单个键排序,但我遇到的问题是我只能按单个键排序,而不能按两个或多个键排序。这会导致类似的问题sample 2,我对行进行排序,但然后对列进行随机排序。

我希望我的行和列都被排序。我怎样才能做到这一点?, 谢谢

Cha*_*man 22

由于 Rust 中的元组PartialOrd实现了字典比较,因此可以使用以下sort_by_key()方法:

my_vector.sort_unstable_by_key(|item| (item.row, item.column));
Run Code Online (Sandbox Code Playgroud)

游乐场


Gun*_*t.r 6

通过整理前两种解决方案的信息以及GitHub Copilot的帮助,这里给出了一个sort by two keys排序方法的可行解决方案:

使用可变向量方法compare上的参数:sort_by

my_vector.sort_by(| a, b | if a.row == b.row {
  a.column.partial_cmp(&b.column).unwrap()
} else {
  a.row.partial_cmp(&b.row).unwrap()
});
Run Code Online (Sandbox Code Playgroud)

并使用:

println!("{:#?}", locations);
Run Code Online (Sandbox Code Playgroud)

会输出:

let mut locations = vec![
  Location {
    row: 1,
    column: 1
  },
  Location {
    row: 1,
    column: 2
  },
  Location {
    row: 2,
    column: 1
  },
  Location {
    row: 2,
    column: 2
  }
];
Run Code Online (Sandbox Code Playgroud)


小智 5

您还可以为 MyStruct < module std::CMP >实现 PartialOrd 或 Ord

use core::cmp::Ordering;

#[derive(Debug, Eq, PartialEq, Ord)]
struct MyStruct {
    row: u8,
    column: u8,
}

impl PartialOrd for MyStruct {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        if self.row == other.row {
            return Some(self.column.cmp(&other.column));
        }
        Some(self.row.cmp(&other.row))
    }
}

fn main() {
    let mut my_vector = vec![
        MyStruct { row: 10, column: 3 },
        MyStruct { row: 10, column: 1 },
        MyStruct { row: 10, column: 2 },
    ];
    my_vector.sort();
    println!("{:?}", my_vector);
}
Run Code Online (Sandbox Code Playgroud)

操场