Подобно 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 по-прежнему предпочтительнее популярного решения Linq 3.5, оно выполняет сортировку на месте и не требует хранения O (n), как подход Linq. Если, конечно, вы не хотите, чтобы исходный объект List оставался нетронутым.
источник
Для версий .Net, где вы можете использовать LINQ
OrderBy
иThenBy
(илиThenByDescending
при необходимости):using System.Linq; .... List<SomeClass>() a; List<SomeClass> b = a.OrderBy(x => x.x).ThenBy(x => x.y).ToList();
Примечание: для .Net 2.0 (или если вы не можете использовать LINQ) см. Ответ Ханса Пассанта на этот вопрос.
источник
Вам необходимо реализовать интерфейс IComparer . Вот хороший пост с примером кода.
источник
Уловка состоит в том, чтобы реализовать стабильную сортировку. Я создал класс 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<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; } }
Вы бы поместили это в класс помощников сортировки, который вы упомянули в своем вопросе.
Теперь, чтобы использовать это:
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); } }
И он выводит:
0:1 0:2 1:1 1:2 Press any key to continue . . .
Вероятно, это можно было бы исправить с помощью каких-то анонимных делегатов, но я оставлю это вам.
РЕДАКТИРОВАТЬ : И NoBugz демонстрирует силу анонимных методов ... так что считайте мою более олдскульной: P
источник
Это может вам помочь, Как отсортировать общий список C #
источник
У меня была проблема, из-за которой OrderBy и ThenBy не давали мне желаемого результата (или я просто не знал, как их правильно использовать).
Я пошел с решением 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)));
источник