Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.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# 按两个属性对列表进行就地排序_C#_List_Class_Reorderlist - Fatal编程技术网

C# 按两个属性对列表进行就地排序

C# 按两个属性对列表进行就地排序,c#,list,class,reorderlist,C#,List,Class,Reorderlist,我有一个类有两个属性,名称和位置。 我想按位置对这个类的列表进行排序,相同位置的元素应该按名称排序。我在一个静态列表上工作,所以我想在适当的地方工作 到目前为止,我设法按一个属性对列表进行排序: list.Sort((x, y) => x.Position.CompareTo(y.Position)); 这段代码正在运行,我已经按位置对列表进行了排序,但我不知道如何实现第二部分。我找到了问题,但我不明白答案 有人能帮我吗?我会用“OrderBy”和“ThenBy”: list = lis

我有一个类有两个属性,名称和位置。 我想按位置对这个类的列表进行排序,相同位置的元素应该按名称排序。我在一个静态列表上工作,所以我想在适当的地方工作

到目前为止,我设法按一个属性对列表进行排序:

list.Sort((x, y) => x.Position.CompareTo(y.Position));
这段代码正在运行,我已经按位置对列表进行了排序,但我不知道如何实现第二部分。我找到了问题,但我不明白答案

有人能帮我吗?

我会用“OrderBy”和“ThenBy”:

list = list.OrderBy(item => item.Name).ToList();
list.Sort((x, y) => x.Position.CompareTo(y.Position));
IEnumerable orderedPersons=persons.OrderBy(item=>item.Position)
.ThenBy(item=>item.Name);

您链接到的答案是正确的。按多个值排序的关键是,次要属性仅在原数相等时才起作用。排序比较的伪代码实现可能是:

compare x and y position
if they differ, return order
else compare name, return order
排序
方法中,如果项目相等,则
(x,y)=>
后面的代码必须返回0;如果第一个项目在第二个项目之前,则返回负数;如果第二个项目在第一个项目之前,则返回正数。
CompareTo
方法将根据这些情况及其参数返回-1、0或1。由于需要比较两个不同的属性,因此需要调用两个
CompareTo
。如果您决定将它们加在一起,您可能会遇到如下情况:

  • x、 位置
  • x、 name>y.name(比较返回值1)
  • 结果0,项目被视为相等,其中您的规则 显然,在这种情况下,x应该排在第一位
为了解决这个问题,我们需要确保名称比较只在位置相等时才起作用。由于
CompareTo
仅返回-1、0或1,如果我们将位置结果乘以2(或任何更大的数字),则名称比较仅会在位置相等时更改结果。(因为
-2+1=-1
2-1=1

因此,使用原始链接答案中的方法,您的代码如下所示:

list.Sort((x, y) => 
    2 * x.Position.CompareTo(y.Position) 
    + x.Name.CompareTo(y.Name));

这隐式地依赖于基础排序算法不改变相等项的顺序。这是迄今为止最可靠的方法。这是按2个属性排序的最简单方法,但确实需要创建一个新列表,而OP不希望这样做。(虽然没有太多理由认为有必要在适当的位置使用列表——如果列表非常大,除了性能之外)@Hamma:我希望这能帮助你理解乘法的存在。你也应该考虑Rene Hilgers的回答。它确实会创建一个新列表,但除非您多次执行此排序,并且您的列表相当大,并且您试图避免GCs,否则您可能不需要担心为此排序创建一个新列表。我正在与通过锁同时访问和修改列表的不同线程合作,因此,我关心的是使行动尽可能快和有效。我理解乘法是给这两个属性一个层次结构。
list.Sort((x, y) => 
    2 * x.Position.CompareTo(y.Position) 
    + x.Name.CompareTo(y.Name));