使用比较器对矢量进行排序,以便动态更改其行为

时间:2017-10-01 12:06:19

标签: sorting vector rust

我有一个自定义结构的向量和一个属性列表,用于按降序优先级排序该向量。例如:

struct TheStruct {
    artist: String,
    title: String,
    date: String,
}

let order_vec: Vec<String> = vec!["artist".to_string(),"title".to_string(),"date".to_string()];
let item_vec: Vec<TheStruct> = Vec::new();

我希望按order_vec给出的顺序对矢量进行排序。在这个例子中,它应该首先按艺术家名称排序,当它相等时,它应该按标题排序。我不想对此排序进行硬编码,因为order_vec会动态更改。

我发现Vec::sort_by采用了比较功能。如何动态生成该功能?有没有办法在没有sort_by的情况下执行此操作?

1 个答案:

答案 0 :(得分:6)

  

如何动态生成该功能

你不是。你有一个特定的闭包,里面有动态行为。

在这里,我们有一个要应用的排序列表。当我们需要比较两个项目时,我们遍历列表。我们使用Ordering::then_with仅在前一次比较为Equal时应用比较:

use std::cmp::Ordering;

#[derive(Debug, Copy, Clone)]
enum Field {
    Artist,
    Title,
    Date,
}

struct TheStruct {
    artist: String,
    title: String,
    date: String,
}

fn main() {
    let mut items: Vec<TheStruct> = vec![];

    use Field::*;
    let orders = vec![Artist, Title];

    items.sort_by(|a, b| {
        orders.iter().fold(Ordering::Equal, |acc, &field| {
            acc.then_with(|| {
                match field {
                    Artist => a.artist.cmp(&b.artist),
                    Title => a.title.cmp(&b.title),
                    Date => a.date.cmp(&b.date),
                }
            })
        })
    })
}

我在字段中使用了枚举,因为当其中一种是未知字段时,我不想处理该做什么。