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(???? => ?????)
SaaS Developer
źródło

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
Marc Gravell
źródło
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 ...)

Jon Skeet
źródło
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();
vampire203
źródło
23
people.OrderBy(person => person.lastname).ToList();
Danimal
źródło
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();
        }
    }
}
Bruno
źródło
5

dla mnie ten przydatny sztuczny przewodnik - Sortowanie na liście ogólnej - zadziałał. pomaga zrozumieć 4 sposoby (przeciążenia) wykonywania tej pracy, z bardzo kompletnymi i jasnymi wyjaśnieniami i prostymi przykładami

  • List.Sort ()
  • List.Sort (porównanie ogólne)
  • List.Sort (Generic IComparer)
  • List.Sort (Int32, Int32, Generic IComparer)
Iman
źródło
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 SrivAstav
źródło
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();
rosselder83
źródło
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;
    }
howserss
źródło
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