繁体   English   中英

如何使用我自己的逻辑对列表进行排序(不按字母顺序或数字顺序)

[英]How to sort a list using my own logic (not alphabetically or numerically)

我花了最后30分钟来查看现有的答案,我认为这是一个常见的问题,但没有什么能够帮助我。 如果这是一个骗局,请道歉。

我有一个对象列表。

List<Journey> journeys;

该对象具有'status'属性 - 这是一个字符串。

class Journey
{
    public string Name;
    public string Status; 
}

我想基于这个字符串进行排序,但不是按字母顺序排序。 状态描述了物体在旅程中的位置,“Enroute”,“Finished”或“Error”。 按升序排序时,我希望它们按以下顺序显示:“错误”,“路由”,“已完成”。 (实际上有比这更多的状态,因此将它们重命名为按字母顺序排列不是一种选择)

除了使用值和排序顺序属性创建“状态”类,然后基于此进行排序之外,我该如何做? 或者这是最好的方法?

您可以在自定义函数内部定义您的排序逻辑,该逻辑提供给比较委托:

List<Journey> list = new List<Journey>();

list.Sort(new Comparison<Journey>((Journey source, Journey compare) => 
{ 
    // here is my custom compare logic
    return // -1, 0 or 1
}));

您需要创建一个实现IComparer<Journey>并相应地实现Compare方法。

你没有提到你是如何准确排序的,但是几乎涉及排序的BCL的所有方法都有一个接受IComparer的重载,以便你可以插入你的逻辑。

另一个想法:

class Journey
{
    public enum JourneyStatus
    {
        Enroute,
        Finished,
        Error
    }

    public string Name;
    public JourneyStatus Status;
}

与OrderBy一起使用:

var journeys = new List<Journey>();
journeys.Add(new Journey() { Name = "Test1", Status = Journey.JourneyStatus.Enroute });
journeys.Add(new Journey() { Name = "Test2", Status = Journey.JourneyStatus.Error });
journeys.Add(new Journey() { Name = "Test3", Status = Journey.JourneyStatus.Finished });
journeys.Add(new Journey() { Name = "Test4", Status = Journey.JourneyStatus.Enroute });

journeys = journeys.OrderBy(x => x.Status).ToList();

foreach (var j in journeys)
    Console.WriteLine("{0} : {1}", j.Name, j.Status);

输出:

Test1 : Enroute
Test4 : Enroute
Test3 : Finished
Test2 : Error

或者您可以修改传递给OrderBy的lambda,以将Status字符串的值映射到int

在某些情况下,你可能想要实现IComparer<T> ,就像Jon说的那样。 它可以帮助将排序逻辑和类定义本身保存在一个位置。

除了使用值和排序顺序属性创建“状态”类,然后基于此进行排序之外,我该如何做?

由于这是一些自定义顺序,您需要创建这样一个类是一个好主意。

Comparer<T>StringComparer类派生,使用您的自定义逻辑实现类,将此类的实例传递给sort方法。

一种方法是为每个项目分配一个订单号。 因此,创建一个数据库表来保存您的项目及其顺序:

Column Name, Column Order
Enrout , 0
Finished, 1
Error, 2

然后,当我填充下拉列表时,我可以按照SQL选择中的顺序而不是名称进行排序。

或者,如果您不想使用数据库,可以更改Status以包含订单,然后只解析Status名称:so Status值可能如下所示:“0,Enrout”,“1,Finished”,“ 2,错误“然后它会自然排序。 然后使用split将命令与名称分开:

string[] statusArr = status.split(',');
string order = statusArr[0];
string statusname = statusArr[1];

有很多方法可以给这只猫上皮。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM