当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C#List<>按x然后y排序》经验,为你挑选了4个好方法。

与List <> OrderBy Alphabetical Order类似,我们希望按一个元素排序,然后按另一个元素排序.我们希望实现功能相当于

SELECT * from Table ORDER BY x, y  

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

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

List MyList;

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

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

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

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



1> Toby..:

对于.Net的版本,您可以使用LINQ OrderByThenBy(或者ThenByDescending如果需要):

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

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


来自phoog的另一篇回复帖子:http://stackoverflow.com/questions/9285426/orderby-and-list-vs-iorderedenumerable它以新的顺序创建另一个包含原始项目的列表.这仅在您需要为其他目的保留原始排序时才有用; 它比内存排序更浪费内存

2> Hans Passant..:

请记住,如果比较所有成员,则不需要稳定的排序.根据要求,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);
     });
 }

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



3> Bill the Liz..:

您需要实现IComparer接口. 这是一篇包含示例代码的好文章.



4> FlySwat..:

诀窍是实现稳定的排序.我创建了一个可以包含测试数据的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;
    }
}

我实现了IComparable,因此它可以通过List.Sort()进行不稳定的排序.

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

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

 public static void InsertionSort(IList list, Comparison 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;
            }
    }

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

现在,使用它:

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

        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(widgets, Widget.Compare);

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

它输出:

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

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

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

推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有