使用比较器对向量进行排序,该比较器会动态更改其行为 [英] Sort a vector with a comparator which changes its behavior dynamically

查看:82
本文介绍了使用比较器对向量进行排序,该比较器会动态更改其行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义结构的向量和一个属性列表,可用于按降序对向量进行排序.例如:

I have a vector of a custom struct and a list of attributes to use for ordering that vector in descending priority. For example:

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是动态变化的,因此我不想对这种顺序进行硬编码.

I want the vector to be ordered as given by order_vec. In this example, it should first be ordered by the artists name, when this is equal it should be ordered by the title. I do not want to hard-code this ordering as order_vec changes dynamically.

我发现Vec::sort_by具有比较功能.如何动态生成该函数?没有sort_by,有没有办法做到这一点?

I found Vec::sort_by which takes a compare function. How do I dynamically generate that function? Is there a way to do this without sort_by?

推荐答案

如何动态生成该函数

How do I dynamically generate that function

你不知道.您有一个内部具有动态行为的特定闭包.

You don't. You have a specific closure that has dynamic behavior inside of it.

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

Here, we have a list of sorts to apply. When we need to compare two items, we iterate through the list. We use Ordering::then_with to only apply the comparison when the previous comparison was 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),
                }
            })
        })
    })
}

我为这些字段使用了一个枚举,因为当一种类型的字段是未知字段时,我不想处理该做什么.

I used an enum for the fields because I didn't want to deal with what to do when one of the sorts is an unknown field.

这篇关于使用比较器对向量进行排序,该比较器会动态更改其行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆