Daftar <T> OrderDengan Urutan Abjad

442

Saya menggunakan C # pada Framework 3.5. Saya ingin cepat menyortir Generik List<T>. Demi contoh ini, katakanlah saya memiliki Daftar Persontipe dengan properti dari nama belakang. Bagaimana cara saya mengurutkan Daftar ini menggunakan ekspresi lambda?

List<Person> people = PopulateList();
people.OrderBy(???? => ?????)
Pengembang SaaS
sumber

Jawaban:

695

Jika yang Anda maksud adalah jenis di tempat (yaitu daftar diperbarui):

people.Sort((x, y) => string.Compare(x.LastName, y.LastName));

Jika Anda bermaksud daftar baru:

var newList = people.OrderBy(x=>x.LastName).ToList(); // ToList optional
Marc Gravell
sumber
2
Saya percaya yang pertama ingin menjadi people.Sort ((x, y) => string.Compare (x.LastName, y.LastName) <0);
James Curran
36
@ James: Saya kira tidak. Perbandingan <T> mengembalikan int, bukan bool.
Jon Skeet
2
Saya ingin tahu apakah Anda ingin OrderBy Firstname dan Lastname ... apa yang harus Anda tulis?
balexandre
63
var newList = people.OrderBy (x => x.FirstName) .ThenBy (x => x.LastName) .ToList ();
Marc Gravell
4
@Faraz (x, y) => x.price.CompareTo (y.price)
Marc Gravell
98

Apakah Anda perlu daftar untuk disortir di tempat, atau hanya urutan yang terurut dari isi daftar? Yang terakhir lebih mudah:

var peopleInOrder = people.OrderBy(person => person.LastName);

Untuk mengurutkan di tempat, Anda akan memerlukan a IComparer<Person>atau a Comparison<Person>. Untuk itu, Anda mungkin ingin mempertimbangkan ProjectionComparerdi MiscUtil .

(Aku tahu aku terus membawa MiscUtil - itu tetap relevan ...)

Jon Skeet
sumber
1
Ini bekerja untuk saya, tetapi hanya setelah saya menambahkan ".ToList ()": contemporariesOrderedByBirthYear = contemporaries.OrderBy (contemp => contemp.BirthYear) .ToList ();
B. Clay Shannon
2
@ B.ClayShannon: Yah Anda membutuhkannya jika Anda menginginkannya List<T>, tetapi Anda tidak membutuhkannya jika Anda hanya ingin mengulanginya.
Jon Skeet
23

Anda dapat menggunakan LINQ :) menggunakan:

System.linq;
var newList = people.OrderBy(x=>x.Name).ToList();
vampire203
sumber
23
people.OrderBy(person => person.lastname).ToList();
Danimal
sumber
17
Nah, itu masih belum menangkap hasilnya - Anda perlu "Daftar <Person> orang =" di sebelah kiri ...
Marc Gravell
8
Jawaban ini menunjukkan kesalahan paling umum saat menggunakan LINQ - metode seperti OrderBy tidak mengubah daftar, tetapi mengembalikan "koleksi" baru (biasanya malas IEnumerable<T>) yang perlu ditugaskan ke sesuatu.
Alexei Levenkov
2
@AlexeiLevenkov bagaimana Anda tahu ini adalah kesalahan paling umum saat menggunakan LINQ?
tymtam
13
private void SortGridGenerico< T >(
          ref List< T > lista       
    , SortDirection sort
    , string propriedadeAOrdenar)
{

    if (!string.IsNullOrEmpty(propriedadeAOrdenar)
    && lista != null
    && lista.Count > 0)
    {

        Type t = lista[0].GetType();

        if (sort == SortDirection.Ascending)
        {

            lista = lista.OrderBy(
                a => t.InvokeMember(
                    propriedadeAOrdenar
                    , System.Reflection.BindingFlags.GetProperty
                    , null
                    , a
                    , null
                )
            ).ToList();
        }
        else
        {
            lista = lista.OrderByDescending(
                a => t.InvokeMember(
                    propriedadeAOrdenar
                    , System.Reflection.BindingFlags.GetProperty
                    , null
                    , a
                    , null
                )
            ).ToList();
        }
    }
}
Bruno
sumber
5

bagi saya panduan boneka berguna ini - Menyortir dalam Daftar Generik - berfungsi. ini membantu Anda untuk memahami 4 cara (kelebihan) untuk melakukan pekerjaan ini dengan penjelasan yang sangat lengkap dan jelas dan contoh-contoh sederhana

  • Daftar. Beragam ()
  • List.Sort (Perbandingan Generik)
  • List.Sort (Generic IComparer)
  • List.Sort (Int32, Int32, Generic IComparer)
Iman
sumber
5

Anda dapat menggunakan potongan kode ini:

var New1 = EmpList.OrderBy(z => z.Age).ToList();

dimana New1a List<Employee>.

EmpListadalah variabel dari a List<Employee>.

zadalah variabel Employeetipe.

AnshuMan SrivAstav
sumber
AnshuMan, tidak ada yang seperti vartipe. New1adalah List<Employee>dan zsekarang Employee.
nawfal
5

Anda juga bisa menggunakan

model.People = model.People.OrderBy(x => x.Name).ToList();
rosselder83
sumber
4
Meskipun contoh kode ini dapat menjawab pertanyaan, namun kekurangan penjelasan. Seperti yang ada sekarang, itu tidak menambah nilai, dan tahan perubahan yang downvoted / dihapus. Silakan tambahkan beberapa penjelasan apa yang dilakukan dan mengapa ini merupakan solusi untuk masalah OP.
oɔɯǝɹ
0

Ini adalah penyortir generik. Disebut dengan sakelar di bawah ini.

dvm.PagePermissions adalah properti pada ViewModel tipe T saya dalam hal ini T adalah kelas model EF6 yang disebut page_permission.

dvm.UserNameSortDir adalah properti string pada viewmodel yang memegang arah pengurutan berikutnya. Yang benar-benar digunakan dalam tampilan.

switch (sortColumn)
{
    case "user_name":
        dvm.PagePermissions = Sort(dvm.PagePermissions, p => p.user_name, ref sortDir);
        dvm.UserNameSortDir = sortDir;
        break;
    case "role_name":
        dvm.PagePermissions = Sort(dvm.PagePermissions, p => p.role_name, ref sortDir);
        dvm.RoleNameSortDir = sortDir;
        break;
    case "page_name":
        dvm.PagePermissions = Sort(dvm.PagePermissions, p => p.page_name, ref sortDir);
        dvm.PageNameSortDir = sortDir;
        break;
}                 


public List<T> Sort<T,TKey>(List<T> list, Func<T, TKey> sorter, ref string direction)
    {
        if (direction == "asc")
        {
            list = list.OrderBy(sorter).ToList();
            direction = "desc";
        }
        else
        {
            list = list.OrderByDescending(sorter).ToList();
            direction = "asc";
        }
        return list;
    }
howserss
sumber
1
Saya pikir ini terlalu rumit. Seperti yang dapat Anda lihat di jawaban lain, semuanya dapat dilakukan dalam satu baris (itu tidak berarti bahwa melakukannya dalam satu baris adalah baik, tetapi saya tidak mendapatkan keuntungan dari melakukannya seperti ini)
jalgames
Ini untuk penyortiran multi kolom menggunakan AngularJS. Ini pada dasarnya adalah penyortiran baris tunggal tetapi juga menetapkan variabel urutan pengarahan. Benar-benar tidak rumit jika Anda melihatnya dengan cermat. Saya kira fungsi Urutkan sedikit mengintimidasi dengan semua hal-hal yang umum tetapi jika saya mengambil definisi itu adalah 1 Urut panggilan.
howserss
Terlalu rumit untuk apa yang diminta OP. Ini adalah solusi yang baik untuk masalah yang berbeda.
bergulung