C# List<> 按 x 然后 y 排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/289010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 21:47:56  来源:igfitidea点击:

C# List<> Sort by x then y

c#.netsorting

提问by Byron Ross

Similar to List<> OrderBy Alphabetical Order, we want to sort by one element, then another. we want to achieve the functional equivalent of

List<> OrderBy Alphabetical Order类似,我们希望先按一个元素排序,然后再按另一个元素排序。我们想要实现的功能等价于

SELECT * from Table ORDER BY x, y  

We have a class that contains a number of sorting functions, and we have no issues sorting by one element.
For example:

我们有一个包含许多排序函数的类,并且按一个元素排序没有问题。
例如:

public class MyClass {
    public int x;
    public int y;
}  

List<MyClass> MyList;

public void SortList() {
    MyList.Sort( MySortingFunction );
}

And we have the following in the list:

我们在列表中有以下内容:

Unsorted     Sorted(x)     Desired
---------    ---------    ---------
ID   x  y    ID   x  y    ID   x  y
[0]  0  1    [2]  0  2    [0]  0  1
[1]  1  1    [0]  0  1    [2]  0  2
[2]  0  2    [1]  1  1    [1]  1  1
[3]  1  2    [3]  1  2    [3]  1  2

Stable sort would be preferable, but not required. Solution that works for .Net 2.0 is welcome.

稳定排序会更可取,但不是必需的。欢迎适用于 .Net 2.0 的解决方案。

采纳答案by Hans Passant

Do keep in mind that you don't need a stable sort if you compare all members. The 2.0 solution, as requested, can look like this:

请记住,如果比较所有成员,则不需要稳定的排序。根据要求,2.0 解决方案可能如下所示:

 public void SortList() {
     MyList.Sort(delegate(MyClass a, MyClass b)
     {
         int xdiff = a.x.CompareTo(b.x);
         if (xdiff != 0) return xdiff;
         else return a.y.CompareTo(b.y);
     });
 }

Do note that this 2.0 solution is still preferable over the popular 3.5 Linq solution, it performs an in-place sort and does not have the O(n) storage requirement of the Linq approach. Unless you prefer the original List object to be untouched of course.

请注意,此 2.0 解决方案仍然优于流行的 3.5 Linq 解决方案,它执行就地排序,并且没有 Linq 方法的 O(n) 存储要求。当然,除非您更喜欢原封不动的 List 对象。

回答by Toby

For versions of .Net where you can use LINQ OrderByand ThenBy(or ThenByDescendingif needed):

对于可以使用 LINQOrderByThenBy(或ThenByDescending如果需要)的 .Net 版本:

using System.Linq;
....
List<SomeClass>() a;
List<SomeClass> b = a.OrderBy(x => x.x).ThenBy(x => x.y).ToList();


Note: for .Net 2.0 (or if you can't use LINQ) see Hans Passant answerto this question.

注意:对于 .Net 2.0(或者如果您不能使用 LINQ),请参阅Hans Passant对此问题的回答。

回答by Bill the Lizard

You need to implement the IComparerinterface. Here's a good postwith example code.

您需要实现IComparer接口。 这是一个带有示例代码的好帖子

回答by FlySwat

The trick is to implement a stable sort. I've created a Widget class that can contain your test data:

诀窍是实现稳定的排序。我创建了一个可以包含您的测试数据的 Widget 类:

public class Widget : IComparable
{
    int x;
    int y;
    public int X
    {
        get { return x; }
        set { x = value; }
    }

    public int Y
    {
        get { return y; }
        set { y = value; }
    }

    public Widget(int argx, int argy)
    {
        x = argx;
        y = argy;
    }

    public int CompareTo(object obj)
    {
        int result = 1;
        if (obj != null && obj is Widget)
        {
            Widget w = obj as Widget;
            result = this.X.CompareTo(w.X);
        }
        return result;
    }

    static public int Compare(Widget x, Widget y)
    {
        int result = 1;
        if (x != null && y != null)                
        {                
            result = x.CompareTo(y);
        }
        return result;
    }
}

I implemented IComparable, so it can be unstably sorted by List.Sort().

我实现了 IComparable,所以它可以通过 List.Sort() 不稳定地排序。

However, I also implemented the static method Compare, which can be passed as a delegate to a search method.

但是,我还实现了静态方法 Compare,它可以作为委托传递给搜索方法。

I borrowed this insertion sort method from C# 411:

我从C# 411借用了这个插入排序方法:

 public static void InsertionSort<T>(IList<T> list, Comparison<T> comparison)
        {           
            int count = list.Count;
            for (int j = 1; j < count; j++)
            {
                T key = list[j];

                int i = j - 1;
                for (; i >= 0 && comparison(list[i], key) > 0; i--)
                {
                    list[i + 1] = list[i];
                }
                list[i + 1] = key;
            }
    }

You would put this in the sort helpers class that you mentioned in your question.

您可以将它放在您在问题中提到的排序助手类中。

Now, to use it:

现在,使用它:

    static void Main(string[] args)
    {
        List<Widget> widgets = new List<Widget>();

        widgets.Add(new Widget(0, 1));
        widgets.Add(new Widget(1, 1));
        widgets.Add(new Widget(0, 2));
        widgets.Add(new Widget(1, 2));

        InsertionSort<Widget>(widgets, Widget.Compare);

        foreach (Widget w in widgets)
        {
            Console.WriteLine(w.X + ":" + w.Y);
        }
    }

And it outputs:

它输出:

0:1
0:2
1:1
1:2
Press any key to continue . . .

This could probably be cleaned up with some anonymous delegates, but I'll leave that up to you.

这可能会与一些匿名代表一起清理,但我会把它留给你。

EDIT: And NoBugz demonstrates the power of anonymous methods...so, consider mine more oldschool :P

编辑:NoBugz 展示了匿名方法的力量......所以,考虑我的更老派:P

回答by mofoo

I had an issue where OrderBy and ThenBy did not give me the desired result (or I just didn't know how to use them correctly).

我遇到了一个问题,OrderBy 和 ThenBy 没有给我想要的结果(或者我只是不知道如何正确使用它们)。

I went with a list.Sort solution something like this.

我使用了一个类似这样的 list.Sort 解决方案。

    var data = (from o in database.Orders Where o.ClientId.Equals(clientId) select new {
    OrderId = o.id,
    OrderDate = o.orderDate,
    OrderBoolean = (SomeClass.SomeFunction(o.orderBoolean) ? 1 : 0)
    });

    data.Sort((o1, o2) => (o2.OrderBoolean.CompareTo(o1.OrderBoolean) != 0
    o2.OrderBoolean.CompareTo(o1.OrderBoolean) : o1.OrderDate.Value.CompareTo(o2.OrderDate.Value)));

回答by Bala

This may help you, How to Sort C# Generic List

这可能对您有所帮助, 如何对 C# 泛型列表进行排序