Elenco <T> Ordine per ordine alfabetico


443

Sto usando C # su Framework 3.5. Sto cercando di ordinare rapidamente un generico List<T>. Per il bene di questo esempio, diciamo che ho un elenco di un Persontipo con una proprietà di cognome. Come potrei ordinare questo elenco usando un'espressione lambda?

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

Risposte:


696

Se si intende un ordinamento sul posto (ovvero l'elenco viene aggiornato):

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

Se intendi un nuovo elenco:

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

2
Credo che il primo voglia essere people.Sort ((x, y) => string.Compare (x.LastName, y.LastName) <0);
James Curran,

36
@James: non la penso così. Il confronto <T> restituisce int, non bool.
Jon Skeet,

2
Mi chiedo se vuoi ordinare per nome e cognome ... cosa dovresti scrivere?
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

È necessario che l'elenco sia ordinato in posizione o solo una sequenza ordinata dei contenuti dell'elenco? Quest'ultimo è più semplice:

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

Per ordinare sul posto, avresti bisogno di un IComparer<Person>o un Comparison<Person>. Per questo, potresti prendere ProjectionComparerin considerazione in MiscUtil .

(So ​​che continuo a portare MiscUtil in su - continua ad essere rilevante ...)


1
Questo ha funzionato per me, ma solo dopo aver aggiunto ".ToList ()": contemporariesOrderedByBirthYear = contemporaries.OrderBy (contemp => contemp.BirthYear) .ToList ();
B. Clay Shannon,

2
@ B.ClayShannon: beh, se ne hai bisogno List<T>, ma non ti serve se vuoi solo iterare.
Jon Skeet,

23

puoi usare linq :) usando:

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

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

17
Bene, questo non cattura ancora il risultato - avresti bisogno di un "Elenco <Person> persone =" sul lato sinistro ...
Marc Gravell

8
Questa risposta dimostra l'errore più comune quando si usano LINQ - metodi come OrderBy non modificare l'elenco, ma piuttosto restituire una nuova "raccolta" (di solito pigra IEnumerable<T>) che deve essere assegnata a qualcosa.
Alexei Levenkov,

2
@AlexeiLevenkov come fai a sapere che questo è l'errore più comune quando si utilizza 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

Puoi utilizzare questo frammento di codice:

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

dov'è New1a List<Employee>.

EmpListè variabile di a List<Employee>.

zè una variabile di Employeetipo.


AnshuMan, non c'è niente come un vartipo. New1è List<Employee>ed zè Employee.
nawfal,

5

Puoi anche usare

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

4
Sebbene questo esempio di codice possa rispondere alla domanda, manca di spiegazione. Così com'è ora, non aggiunge alcun valore e sopporta il cambiamento di essere ridimensionato / eliminato. Si prega di aggiungere alcune spiegazioni su cosa fa e perché è una soluzione al problema del PO.
o

0

Questo è un selezionatore generico. Chiamato con l'interruttore qui sotto.

dvm.PagePermissions è una proprietà sul mio ViewModel di tipo Elenco T in questo caso T è una classe di modello EF6 chiamata page_permission.

dvm.UserNameSortDir è una proprietà di stringa nel viewmodel che contiene la direzione di ordinamento successiva. Quello che viene utilizzato attivamente nella vista.

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
Penso che sia troppo complicato. Come puoi vedere nelle altre risposte, tutto può essere fatto in una sola riga (non significa necessariamente che farlo in una sola riga sia buono, ma non ho il vantaggio di farlo in questo modo)
jalgames

Questo è per l'ordinamento a più colonne usando AngularJS. È essenzialmente l'ordinamento a riga singola ma imposta anche la variabile di direzione dell'ordinamento. Non è poi così complesso se lo guardi da vicino. Immagino che la funzione di ordinamento sia un po 'intimidatoria con tutte le cose generiche, ma se ho preso quella definizione è una chiamata di ordinamento su 1 riga.
Howsers

Troppo complicato per ciò che l'OP ha richiesto. È comunque una buona soluzione per un problema diverso.
lancia il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.