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

gdrx4gfi  于 2022-11-12  发布在  其他
关注(0)|答案(5)|浏览(326)

example

struct MyStruct{
    row: u8,
    column: u8
}

let my_vector = a Vec<MyStruct> with like 100 items in it

假设我有一个简单的设置,比如说,我想对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 }, ]

sample 2

my_vector = vec![
MyStruct { row: 10, column: 3 },
MyStruct { row: 10, column: 1 },
MyStruct { row: 10, column: 2 }, ]

目前我正在编写this post,它描述了如何使用sort_by_key()函数按单个键排序,但我遇到的问题是我只能按单个键排序,而不能按两个或多个键排序。这导致了像sample 2这样的问题,我对行进行了排序,但对列的排序是随机的。

我希望行和列都是有序的。如何做到这一点?,谢谢

vh0rcniy

vh0rcniy1#

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

my_vector.sort_unstable_by_key(|item| (item.row, item.column));

Playground

wj8zmpe1

wj8zmpe12#

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

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);
}

playground

huwehgph

huwehgph3#

通过整理前两个解决方案的信息,并在GitHub Copilot的帮助下,这里有一个sort by two keys排序方法的工作解决方案:
在可变向量的sort_by方法上使用compare参数:

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()
});

并使用:

println!("{:#?}", locations);

将输出:

let mut locations = vec![
  Location {
    row: 1,
    column: 1
  },
  Location {
    row: 1,
    column: 2
  },
  Location {
    row: 2,
    column: 1
  },
  Location {
    row: 2,
    column: 2
  }
];
iklwldmw

iklwldmw4#

你可以使用sort_by()

my_vector.sort_by(|a, b| ...);

通过a和B,u可以设置条件,以便为排序link返回true

5w9g7ksd

5w9g7ksd5#

我认为使用match是一个更好的选择,因为它只比较每一对一次。使用sort_unstable_by可能会更好一些,因为unstable更快,而且可以使任何比较反向进行(降序)--只需为cmp()调用交换ab

struct MyStruct{
    row: u8,
    column: u8
}

fn sort(items: &mut [MyStruct]) {
    items.sort_unstable_by(|a, b| {
        match a.row.cmp(&b.row) {
            Ordering::Equal => { a.column.cmp(&b.column) }
            v => { v }
        }
    });
}

相关问题