Linq自定义OrderBy使用常量

时间:2015-10-30 14:17:17

标签: c# linq

我正在尝试对具有ID的项目列表进行排序,但我想基于常量实现自定义排序顺序。以下是有效的,但我不是lambda表达的忠实粉丝。有更好的方法吗?

using System.Collections.Generic;
using System.Linq;
using System;

public class Program
{
    public static void Main()
    {
        var myList = new List<MyItem> 
        {
          new MyItem {SomeId = 1}, 
          new MyItem {SomeId = 2}, 
          new MyItem {SomeId = 3}, 
          new MyItem {SomeId = 4}, 
          new MyItem {SomeId = 5}
        };

        var orderedList = myList
          .OrderBy(list => list.SomeId == SomeIdConstants.FIRST 
            ? 1 
            : list.SomeId == SomeIdConstants.SECOND 
              ? 2 
              : list.SomeId == SomeIdConstants.THIRD 
                ? 3 
                : list.SomeId == SomeIdConstants.FOURTH 
                  ? 4 : 5);

        foreach (var listItem in orderedList)
        {
            Console.WriteLine(listItem.SomeId);
        }
    }
}

public class MyItem
{
    public int SomeId { get; set; }
}

public class SomeIdConstants
{
    public const int FIRST = 2;
    public const int SECOND = 1;
    public const int THIRD = 4;
    public const int FOURTH = 5;
    public const int FIFTH = 3;
}

3 个答案:

答案 0 :(得分:6)

您可以改为使用List,例如

var lookup = new List<int> {2, 1, 4, 5, 3};
var orderedList = myList.OrderBy(list => lookup.IndexOf(list.SomeId));

这会为元素添加一个不在lookup前面的SomeId(这对你来说可能是也可能不是。如果是的话,处理这个问题很简单。)

答案 1 :(得分:4)

您可以将它们放入有序集合中:

int[] orderConstants = { SomeIdConstants.FIRST, SomeIdConstants.SECOND, SomeIdConstants.THIRD, SomeIdConstants.FOURTH, SomeIdConstants.FIFTH };

然后您可以使用Array.IndexOf(如果您将它们放入列表中使用List.IndexOf):

var orderedList = myList.OrderBy(i => Array.IndexOf(orderConstants, i.SomeId));

答案 2 :(得分:0)

使用自定义比较器

编辑:使用枚举

class Program
{
    static void Main(string[] args)
    {
        var myList = new List<MyItem>
        { 
            new MyItem { SomeId = 1 },
            new MyItem { SomeId = 2 },
            new MyItem { SomeId = 3 },
            new MyItem { SomeId = 4 },
            new MyItem { SomeId = 5 }
        };

        var orderedList = myList.OrderBy(d => d, new MyItemComparer());
        foreach (var listItem in orderedList)
        {
            Console.WriteLine(listItem.SomeId);
        }
        Console.ReadLine();
    }
}

public class MyItem
{
    public int SomeId { get; set; }
}

public class MyItemComparer : IComparer<MyItem>
{
    public int Compare(MyItem i1, MyItem i2)
    {
        int pos1 = pos(i1);
        int pos2 = pos(i2);

        if (pos1 > pos2) { return 1; }
        if (pos1 < pos2) { return -1; }
        return 0;
    }

    // Return the required position for a value of SomeId
    private int pos(MyItem it)
    {
        switch (it.SomeId)
        {
            case (int)SomeIdConstants.FIRST: return 1;
            case (int)SomeIdConstants.SECOND: return 2;
            case (int)SomeIdConstants.THIRD: return 3;
            case (int)SomeIdConstants.FOURTH: return 4;
            case (int)SomeIdConstants.FIFTH: return 5;
            default: return 999;
        }
    }
}

public enum SomeIdConstants : int
{
    FIRST = 2,
    SECOND = 1,
    THIRD = 4,
    FOURTH = 5,
    FIFTH = 3
}