Mirip dengan List <> OrderBy Alphabetical Order , kami ingin mengurutkan berdasarkan satu elemen, lalu elemen lainnya. kami ingin mencapai kesetaraan fungsional
SELECT * from Table ORDER BY x, y
Kami memiliki kelas yang berisi sejumlah fungsi pengurutan, dan kami tidak memiliki masalah pengurutan berdasarkan satu elemen.
Sebagai contoh:
public class MyClass {
public int x;
public int y;
}
List<MyClass> MyList;
public void SortList() {
MyList.Sort( MySortingFunction );
}
Dan kami memiliki yang berikut ini dalam daftar:
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
Jenis yang stabil akan lebih disukai, tetapi tidak diharuskan. Solusi yang berfungsi untuk .Net 2.0 diterima.
Jawaban:
Ingatlah bahwa Anda tidak memerlukan jenis yang stabil jika Anda membandingkan semua anggota. Solusi 2.0, seperti yang diminta, dapat terlihat seperti ini:
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); }); }
Perhatikan bahwa solusi 2.0 ini masih lebih disukai daripada solusi 3.5 Linq yang populer, ia melakukan pengurutan di tempat dan tidak memiliki persyaratan penyimpanan O (n) dari pendekatan Linq. Kecuali jika Anda lebih suka objek List asli tidak tersentuh tentunya.
sumber
Untuk versi .Net tempat Anda dapat menggunakan LINQ
OrderBy
danThenBy
(atauThenByDescending
jika perlu):using System.Linq; .... List<SomeClass>() a; List<SomeClass> b = a.OrderBy(x => x.x).ThenBy(x => x.y).ToList();
Catatan: untuk .Net 2.0 (atau jika Anda tidak dapat menggunakan LINQ) lihat jawaban Hans Passant untuk pertanyaan ini.
sumber
Anda perlu menerapkan antarmuka IComparer . Ini posting bagus dengan kode contoh.
sumber
Triknya adalah dengan menerapkan semacam stabil. Saya telah membuat kelas Widget yang dapat berisi data pengujian Anda:
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; } }
Saya menerapkan IComparable, sehingga dapat diurutkan secara tidak stabil berdasarkan List.Sort ().
Namun, saya juga menerapkan metode Bandingkan statis, yang dapat dikirimkan sebagai delegasi ke metode pencarian.
Saya meminjam metode penyisipan semacam ini dari 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; } }
Anda akan memasukkan ini ke dalam kelas penolong yang Anda sebutkan dalam pertanyaan Anda.
Sekarang, untuk menggunakannya:
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); } }
Dan itu menghasilkan:
0:1 0:2 1:1 1:2 Press any key to continue . . .
Ini mungkin bisa dibersihkan dengan beberapa delegasi anonim, tapi saya serahkan pada Anda.
EDIT : Dan NoBugz mendemonstrasikan kekuatan metode anonim ... jadi, pertimbangkan sekolah saya yang lebih tua: P
sumber
Ini dapat membantu Anda, Cara Menyortir C # Daftar Generik
sumber
Saya mengalami masalah di mana OrderBy dan ThenBy tidak memberi saya hasil yang diinginkan (atau saya hanya tidak tahu cara menggunakannya dengan benar).
Saya pergi dengan daftar. Solusi sortir seperti ini.
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)));
sumber