Saya memiliki kelas yang disebut Order
yang memiliki properti sepertiOrderId
, OrderDate
, Quantity
, dan Total
. Saya punya daftar Order
kelas ini :
List<Order> objListOrder = new List<Order>();
GetOrderList(objListOrder); // fill list of orders
Sekarang saya ingin mengurutkan daftar berdasarkan pada satu properti Order
objek, misalnya saya perlu mengurutkannya berdasarkan tanggal pesanan atau id pesanan.
Bagaimana saya bisa melakukan ini dalam C #?
Jawaban:
Cara termudah yang bisa saya pikirkan adalah menggunakan Linq:
sumber
listWithObjects = listWithObjects.OrderByDescending(o => o.Status).ToList();
cukup untuk usaha seperti itu?Jika Anda perlu mengurutkan daftar di tempat maka Anda dapat menggunakan
Sort
metode ini, melewatiComparison<T>
delegasi:Jika Anda lebih suka membuat urutan baru yang diurutkan daripada mengurutkan di tempat maka Anda dapat menggunakan
OrderBy
metode LINQ , seperti yang disebutkan dalam jawaban lain.sumber
x
dany
di sisi kanan panah=>
.Nullable<>
(ambilDateTime?
sebagai contoh) Anda dapat menggunakan.Sort((x, y) => Nullable.Compare(x.OrderDate, y.OrderDate))
yang akan memperlakukan null sebagai mendahului semua nilai non-nol. Persis sama dengan.Sort((x, y) => Comparer<DateTime?>.Default.Compare(x.OrderDate, y.OrderDate)
.Untuk melakukan ini tanpa LINQ di .Net2.0:
Jika Anda berada di .Net3.0, maka LukeH ini jawabannya adalah yang Anda cari.
Untuk mengurutkan beberapa properti, Anda masih bisa melakukannya di dalam delegasi. Sebagai contoh:
Ini akan memberi Anda tanggal naik dengan turun orderIds.
Namun, saya tidak akan merekomendasikan menempel delegasi karena akan berarti banyak tempat tanpa menggunakan kembali kode. Anda harus menerapkan
IComparer
dan hanya meneruskannya keSort
metode Anda . Lihat di sini .Dan kemudian untuk menggunakan kelas IComparer ini, cukup instantiate dan berikan ke metode Sortir Anda:
sumber
IComparer
implementasi yang berbeda , memberi kita perilaku polimorfik.Cara termudah untuk memesan daftar adalah menggunakan
OrderBy
Jika Anda ingin memesan dengan beberapa kolom seperti mengikuti SQL Query.
Untuk mencapai ini, Anda dapat menggunakan
ThenBy
seperti berikut.sumber
Melakukannya tanpa Linq seperti yang Anda katakan:
Kemudian panggil saja .sort () pada daftar Pesanan Anda
sumber
null
padaas
pemain. Yang merupakan inti darias
, karena (ha, ha)(Order)obj
melempar pengecualian ketika gagal.if(orderToCompare == null) return 1;
.as
kembalinull
jika para pemain gagal. Tapi setidaknya tes nol itu benar.List<Order>
sehingga jenisnya harus dijamin sesuai padaas
2014 sehingga Anda mungkin tidak menulis bug, seperti menghindari pernyataan penjaga yang tidak perlu :)List<Order>
; tetapi Anda dan saya sama-sama telah bertemu dengan programer enkapsulasi diri yang anggapan tak terucapkan adalah "Saya menulis kode ini sehingga tidak akan digunakan salah"Solusi Berorientasi Objek Klasik
Pertama-tama saya harus mengarahkan pada kedahsyatan LINQ .... Sekarang kita sudah menyingkir
Variasi jawaban JimmyHoffa. Dengan obat generik,
CompareTo
parameter menjadi aman.Sortasi default ini tentu saja dapat digunakan kembali. Artinya setiap klien tidak perlu menulis ulang logika sorting secara berlebihan. Mengganti "1" dan "-1" (atau operator logika, pilihan Anda) membalik urutan.
sumber
this
objek lebih besar dari nol. Untuk keperluan pengurutan, referensi objek nol "kurang dari"this
objek. Itulah cara saya memutuskan untuk menentukan bagaimana null akan mengurutkan.// Penyortiran yang benar-benar generik untuk digunakan dengan gridview
sumber
data.OrderBy()
,. Agak lebih mudah menemukan kembali roda.Berikut adalah metode ekstensi LINQ umum yang tidak membuat salinan tambahan dari daftar:
Untuk menggunakannya:
Baru-baru ini saya membuat tambahan ini yang menerima
ICompare<U>
, sehingga Anda dapat menyesuaikan perbandingan. Ini berguna ketika saya perlu melakukan semacam string alami:sumber
OrderBy
melakukan semua itu secara internal.void
metode ekstensi dalam semangat ini:static class Extensions { public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector) { self.SortBy(keySelector, Comparer<TKey>.Default); } public static void SortBy<TSource, TKey>(this List<TSource> self, Func<TSource, TKey> keySelector, IComparer<TKey> comparer) { self.Sort((x, y) => comparer.Compare(keySelector(x), keySelector(y))); } }
Dapat ditambah denganSortByDescending
metode. Komentar @ Servy berlaku untuk kode saya juga!Menggunakan LINQ
sumber
sumber
Peningkatan versi Roger.
Masalah dengan GetDynamicSortProperty adalah bahwa hanya mendapatkan nama properti tetapi apa yang terjadi jika di GridView kita menggunakan NavigationProperties? itu akan mengirim pengecualian, karena ia menemukan nol.
Contoh:
"Employee.Company.Name;" akan macet ... karena hanya mengizinkan "Nama" sebagai parameter untuk mendapatkan nilainya.
Berikut adalah versi yang disempurnakan yang memungkinkan kami untuk mengurutkan berdasarkan Properti Navigasi.
sumber
Anda dapat melakukan sesuatu yang lebih umum tentang pemilihan properti namun spesifik tentang jenis yang Anda pilih, dalam kasus Anda 'Pesan':
tulis fungsi Anda sebagai fungsi umum:
dan kemudian gunakan seperti ini:
Anda bisa menjadi lebih generik dan mendefinisikan tipe terbuka untuk apa yang ingin Anda pesan:
dan gunakan dengan cara yang sama:
Yang merupakan cara kompleks bodoh yang tidak perlu dalam melakukan gaya LINQ 'OrderBy', Tapi itu mungkin memberi Anda petunjuk tentang bagaimana hal itu dapat diterapkan dengan cara yang umum
sumber
Tolong izinkan saya menyelesaikan jawaban oleh @LukeH dengan beberapa kode sampel, karena saya telah mengujinya, saya yakin ini mungkin berguna untuk beberapa:
sumber
sumber
Manfaatkan LiNQ
OrderBy
sumber
Berdasarkan GenericTypeTea 's Comparer:
kami dapat memperoleh lebih banyak fleksibilitas dengan menambahkan flag sorting:
Dalam skenario ini, Anda harus instantiate sebagai MyOrderingClass secara eksplisit (bukan IComparer )
untuk mengatur properti penyortirannya:
sumber
Tidak ada jawaban di atas yang cukup umum untuk saya, jadi saya buat yang ini:
Hati-hati pada set data besar. Ini kode yang mudah tetapi bisa membuat Anda dalam kesulitan jika koleksi sangat besar dan jenis objek koleksi memiliki sejumlah besar bidang. Run time adalah NxM di mana:
N = # Elemen dalam koleksi
M = # Properti dalam Objek
sumber
Siapa pun yang bekerja dengan tipe nullable,
Value
wajib menggunakanCompareTo
.objListOrder.Sort((x, y) => x.YourNullableType.Value.CompareTo(y.YourNullableType.Value));
sumber
Dari sudut pandang kinerja, yang terbaik adalah dengan menggunakan daftar yang diurutkan sehingga data diurutkan saat ditambahkan ke hasil. Pendekatan lain membutuhkan setidaknya satu iterasi ekstra pada data dan sebagian besar membuat salinan data sehingga tidak hanya kinerja tetapi penggunaan memori juga akan terpengaruh. Mungkin tidak menjadi masalah dengan beberapa elemen tetapi akan dengan ribuan, terutama dalam layanan di mana banyak permintaan bersamaan dapat melakukan penyortiran pada saat yang sama. Lihatlah System.Collections. namespace Umum dan pilih kelas dengan menyortir bukan Daftar.
Dan hindari implementasi generik menggunakan refleksi bila memungkinkan, ini dapat menyebabkan masalah kinerja juga.
sumber
Misalkan Anda memiliki kode berikut, dalam kode ini, kami memiliki kelas Penumpang dengan beberapa properti yang ingin kami urutkan berdasarkan.
Jadi, Anda dapat menerapkan struktur pengurutan dengan menggunakan delegasi Komposisi.
sumber