IT story

C # 목록 <> x 순으로 정렬

hot-time 2020. 9. 10. 18:59
반응형

C # 목록 <> x 순으로 정렬


List <> OrderBy Alphabetical Order유사하게 한 요소를 기준으로 정렬 한 다음 다른 요소를 기준으로 정렬하려고합니다. 우리는 다음과 같은 기능을 얻고 싶습니다.

SELECT * from Table ORDER BY x, y  

여러 정렬 기능을 포함하는 클래스가 있으며 하나의 요소로 정렬하는 데 문제가 없습니다.
예를 들면 :

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

List<MyClass> 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에서 작동하는 솔루션은 환영합니다.


모든 멤버를 비교하는 경우 안정적인 정렬이 필요하지 않습니다. 요청에 따라 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 개체를 변경하지 않으려는 경우가 아니면.


당신이 LINQ 사용할 수있는 닷넷의 버전 OrderByThenBy(또는 ThenByDescending필요한 경우) :

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

참고 : .Net 2.0 (또는 LINQ를 사용할 수없는 경우)의 경우이 질문에 대한 Hans Passant 답변참조 하세요.


IComparer 인터페이스 를 구현해야합니다 . 다음 은 예제 코드 가 포함 된 좋은 게시물 입니다.


트릭은 안정적인 정렬을 구현하는 것입니다. 테스트 데이터를 포함 할 수있는 위젯 클래스를 만들었습니다.

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 ()에 의해 불안정하게 정렬 될 수 있습니다.

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

I borrowed this insertion sort method from 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


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


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).

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

    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)));

참고URL : https://stackoverflow.com/questions/289010/c-sharp-list-sort-by-x-then-y

반응형