按相同值字段降序排序列表

3

如何对泛型列表中相同值的字段按降序排序。

示例:

List<int> objList = new List<int>();

objList.Add(1);
-> objList.Add(0);
-> objList.Add(0);
objList.Add(2);
-> objList.Add(0);

这是我的某种源代码,我想按照降序的方式排序零值。

我使用以下代码来排序数字(实际上是深度),上面的例子与此无关,但在某种程度上是相同的。在我的通用列表中,有几个深度可能彼此相同,我想按照相同字段进行降序排序。

Objects.Sort(
   delegate(Classes.Object.GameObject Object1, Classes.Object.GameObject Object2)
   {
       return Object1.Depth.CompareTo(Object2.Depth);
   }
);

回答: 可能会帮助将来的某个人

    // Reverse same oredered
    CurrentSameOrderedFind = Objects[0].Depth;
    CurrentSameOrderedID = 0;
    for (int i = 1; i <= Objects.Count - 1; i++)
    {
        if (Objects[i].Depth != CurrentSameOrderedFind)
        {
            SameOrederedFound = true;
            Objects.Reverse(CurrentSameOrderedID, i - 1);
            CurrentSameOrderedFind = Objects[i].Depth;
            CurrentSameOrderedID = i;
        }
    }
    if (!SameOrederedFound)
    {
        Objects.Reverse();
    }

1
你的问题非常不清楚。例如,“上面的例子与此无关,但在某种程度上它是相同的” - 这是什么意思?如果您能更清楚地解释问题,我们更有可能能够帮助您。 - Jon Skeet
我不知道我应该再展开多少。很简单,按相同值的字段按降序重新排序。就像你有 (Field[0] = 0, Field[1] = 1, Field[2] = 0) 然后结果应该是 (Field[2], Field[0], Field[1]); 很容易! - MahanGM
不,这并不容易——你所说的“相同值字段”是什么意思?如果您能提供一个简短但完整的示例,展示您的输入和期望输出,那将非常有帮助。 - Jon Skeet
2个回答

4
要将一个List<int>按降序排序,你可以使用非常简单的Linq解决方案:objList = objList.OrderByDescending(i => i).ToList(); 从你问题的其余部分来看,你想要对一个具有depth属性的对象列表进行排序?如果是这样,以下代码可以帮助你:
var myList = new List<someTypeWithDepth>();
myList = myList.OrderByDescending(o => o.depth).ToList();

如果在任何情况下,您正在使用这些列表,并且可以将它们键入为IEnumerable<T>而不是List<T>,那么您可以删除那些丑陋的ToList()调用。

1
OrderByDescending调用(与所有LINQ一样)不会对List<T>进行排序,它们将返回已排序的数据作为IOrderedEnumerable<TSource>。 - Aaron McIver
好棒!我会试试看。但是Aron Mclver说了什么? - MahanGM
@MahanGM - Aaron指出了我的代码中的一个小错误。现在应该已经修复了。 - Adam Rackis

1

如果我理解你的意思,你想根据 GameObject.Depth 以降序对列表进行排序,而你已经有了一个按升序而不是降序排序的实现。考虑到这一点,下面是我能想出来的最懒的答案:

根据我的评论修改了代码。真的,为什么你在问题中不能直接说明你想要的?我同意这并不复杂,但如果你不提出好问题,就不会得到好的帮助。

   List<GameObject> oldList = new List<GameObject>(Objects); 
   Objects.Sort( 
       delegate(Classes.Object.GameObject Object1, Classes.Object.GameObject Object2) 
       { 
           int compareValue = -1 * Object1.Depth.CompareTo(Object2.Depth); 
           if(compareValue == 0)
               compareValue = oldList.IndexOf(Object2).CompareTo(oldList.IndexOf(Object1));
           return compareValue;
       } 
    ); 

这并不是最优解,但它也不需要最优。


@MahanGM - 然后你需要一个额外的属性进行比较,至少对于你已经使用的delegate语法,你还没有指定一个。我将编辑我的答案,使用列表索引作为该属性(按降序排列,因此如果它们具有相同的深度,则list[0]会出现在list[1]之后),因为我怀疑这就是你想要的,基于你问题的评论。 - Esoteric Screen Name
我做了,但是他们问了一些问题,很少有明确的重点!关于更新的代码,看起来不错,但只是关心零值吗?相同的值可以是任何数字。 - MahanGM
@MahanGM - 这段代码将根据 Depth(较高的值优先)和前一个索引值(同样是最高的)对您的列表(Objects)进行排序。因此,如果 Objects = { A, B, C, D },其相应的深度值�� { 1, 0, 2, 0 },则排序结果将为 { C, A, D, B }。如果您希望首先按低深度排序,但仍然是最高索引优先 - 即结果为 { D, B, A, C } - 只需删除 -1 * 即可。 - Esoteric Screen Name
现在这才是我想要的一个小时!谢谢。我会把你的名字放在我的鸣谢中 :) - MahanGM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接