Lista <T> Zamówienie według kolejności alfabetycznej


442

Używam C # na Framework 3.5. Chcę szybko posortować ogólny List<T>. Na potrzeby tego przykładu załóżmy, że mam listę Persontypu z właściwością nazwiska. Jak posortować tę listę za pomocą wyrażenia lambda?

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

Odpowiedzi:


695

Jeśli masz na myśli sortowanie na miejscu (tj. Lista jest aktualizowana):

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

Jeśli masz na myśli nową listę:

var newList = people.OrderBy(x=>x.LastName).ToList(); // ToList optional

2
Wierzę, że pierwszy chce być people.Sort ((x, y) => string.Compare (x.LastName, y.LastName) <0);
James Curran

36
@James: Nie sądzę. Porównanie <T> zwraca wartość int, a nie bool.
Jon Skeet,

2
Zastanawiam się, czy chcesz zamówić według imienia i nazwiska ... co napisać?
balexandre 16.04.2009

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

Czy potrzebujesz posortować listę, czy tylko uporządkowaną sekwencję zawartości listy? To drugie jest łatwiejsze:

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

Do sortowania w miejscu, to potrzebny jest IComparer<Person>albo Comparison<Person>. W tym celu warto rozważyć ProjectionComparerw MiscUtil .

(Wiem, że ciągle podnoszę MiscUtil - to po prostu jest aktualne ...)


1
To działało dla mnie, ale dopiero po dodaniu „.ToList ()”: contemporariesOrdersByBirthYear = contemporaries.OrderBy (contemp => contemp.BirthYear) .ToList ();
B. Clay Shannon

2
@ B.ClayShannon: Cóż, potrzebujesz tego, jeśli chcesz List<T>, ale nie potrzebujesz go, jeśli chcesz tylko iterować.
Jon Skeet,

23

możesz użyć linq :) używając:

System.linq;
var newList = people.OrderBy(x=>x.Name).ToList();

23
people.OrderBy(person => person.lastname).ToList();

17
Cóż, to wciąż nie uchwyca wyniku - potrzebna byłaby „Lista <Osoba> osób =” po lewej stronie ...
Marc Gravell

8
Ta odpowiedź demonstruje najczęstszy błąd podczas korzystania z LINQ - metody takie jak OrderBy nie modyfikuj listy, ale zwracają nową „kolekcję” (zwykle leniwą IEnumerable<T>), którą należy przypisać do czegoś.
Aleksiej Lewenkow

2
@AlexeiLevenkov, skąd wiesz, że jest to najczęstszy błąd podczas korzystania z 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();
        }
    }
}


5

Możesz użyć tego fragmentu kodu:

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

gdzie New1jest List<Employee>.

EmpListjest zmienny List<Employee>.

zjest zmienną Employeetypu.


AnshuMan, nie ma to jak vartyp. New1jest List<Employee>i zjest Employee.
nawfal

5

Możesz także użyć

model.People = model.People.OrderBy(x => x.Name).ToList();

4
Chociaż ten przykładowy kod może odpowiedzieć na pytanie, brakuje mu wyjaśnienia. W obecnym stanie nie dodaje żadnej wartości i stoi w sprzeczności z oceną / usunięciem. Dodaj wyjaśnienie, co robi i dlaczego jest to rozwiązanie problemu PO.
o

0

To jest ogólny sorter. Wywoływany za pomocą przełącznika poniżej.

dvm.PagePermissions jest właściwością w moim modelu ViewModel typu List T, w tym przypadku T jest klasą modelu EF6 o nazwie page_permission.

dvm.UserNameSortDir to właściwość string w modelu viewmodel, która przechowuje następny kierunek sortowania. Ten, który jest faktycznie używany w widoku.

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

1
Myślę, że jest to zbyt skomplikowane. Jak widać w innych odpowiedziach, wszystko to można zrobić w jednym wierszu (niekoniecznie oznacza to, że robienie tego w jednym wierszu jest dobre, ale nie mam przewagi, że robię to w ten sposób)
jalgames,

Służy do sortowania wielu kolumn za pomocą AngularJS. Jest to zasadniczo sortowanie według pojedynczego wiersza, ale ustawia również zmienną kierunku sortowania. To naprawdę nie jest takie skomplikowane, jeśli przyjrzysz się temu uważnie. Wydaje mi się, że funkcja Sort jest nieco onieśmielająca wszystkimi ogólnymi rzeczami, ale jeśli wezmę tę definicję, jest to wywołanie sortowania z 1 linią.
howserss

Zbyt skomplikowane w stosunku do tego, czego zażądał Op. Jest to jednak dobre rozwiązanie innego problemu.
rolki
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.