Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用常量的Linq自定义OrderBy_C#_Linq - Fatal编程技术网

C# 使用常量的Linq自定义OrderBy

C# 使用常量的Linq自定义OrderBy,c#,linq,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>

我试图对具有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;
}
使用System.Collections.Generic;
使用System.Linq;
使用制度;
公共课程
{
公共静态void Main()
{
var myList=新列表
{
新的MyItem{SomeId=1},
新的MyItem{SomeId=2},
新的MyItem{SomeId=3},
新的MyItem{SomeId=4},
新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(orderedList中的var listItem)
{
Console.WriteLine(listItem.SomeId);
}
}
}
公共类MyItem
{
公共int SomeId{get;set;}
}
公共类SomeIdConstants
{
公共const int FIRST=2;
公共常数int秒=1;
第三公共常数=4;
第四公共常数=5;
第五公共常数=3;
}

您可以使用
列表
代替,如

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

这会将带有SomeId的元素放在前面,而SomeId不在
查找中(这可能是您的问题,也可能不是您的问题。如果是,则处理此问题很简单)。

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

int[] orderConstants = { SomeIdConstants.FIRST, SomeIdConstants.SECOND, SomeIdConstants.THIRD, SomeIdConstants.FOURTH, SomeIdConstants.FIFTH };
然后可以使用
Array.IndexOf
(如果已将它们放入列表中,请使用
list.IndexOf
):


使用自定义比较器

编辑:对订单使用枚举

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
}
类程序
{
静态void Main(字符串[]参数)
{
var myList=新列表
{ 
新的MyItem{SomeId=1},
新的MyItem{SomeId=2},
新的MyItem{SomeId=3},
新的MyItem{SomeId=4},
新MyItem{SomeId=5}
};
var orderedList=myList.OrderBy(d=>d,新的MyItemComparer());
foreach(orderedList中的var listItem)
{
Console.WriteLine(listItem.SomeId);
}
Console.ReadLine();
}
}
公共类MyItem
{
公共int SomeId{get;set;}
}
公共类MyItemComparer:IComparer
{
公共整数比较(MyItem i1、MyItem i2)
{
int pos1=pos(i1);
int pos2=pos(i2);
如果(pos1>pos2){return 1;}
if(pos1
公共枚举SomeIdConstants:int
可能比类更好,您确定
FIRST=2
吗?@b我相信OP的意思是2的值应该放在第一位。您可以使用带有
I比较程序的
OrderBy
@我只是想确认这些常数是正确的。我遵循的是值->顺序映射。@B我也可以使用枚举,但juharr是正确的,在这个例子中我只想要2,1,4,5,3的顺序。不清楚这些常量是如何起作用的。如果OP希望通过更改常量值对所有查询重新排序,该怎么办?他还必须记住,可能有一些集合不引用常量,但含义相同。我最终使用了sloth的答案与列表和您的答案的组合,但选择了您的答案,因为它确实使用了我最初问题中的常量。我知道常数在这个例子中可能没有什么意义,但我使用的实际常数是一个映射到类型表的类,所以我希望能够在一个地方更改它。谢谢你的帮助!
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
}