Lista <T> OrdenPor orden alfabético

442

Estoy usando C # en Framework 3.5. Estoy buscando ordenar rápidamente un genérico List<T>. Por el bien de este ejemplo, digamos que tengo una Lista de un Persontipo con una propiedad de apellido. ¿Cómo ordenaría esta lista usando una expresión lambda?

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

Respuestas:

695

Si se refiere a una ordenación in situ (es decir, la lista se actualiza):

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

Si te refieres a una nueva lista:

var newList = people.OrderBy(x=>x.LastName).ToList(); // ToList optional
Marc Gravell
fuente
2
Creo que el primero quiere ser personas. Ordenar ((x, y) => string.Compare (x.LastName, y.LastName) <0);
James Curran
36
@ James: No lo creo. La comparación <T> devuelve int, no bool.
Jon Skeet
2
Me pregunto si desea ordenar por nombre y apellido ... ¿qué debe escribir?
balexandre
63
var newList = people.OrderBy (x => x.FirstName) .ThenBy (x => x.LastName) .ToList ();
Marc Gravell
44
@Faraz (x, y) => x.price.CompareTo (y.price)
Marc Gravell
98

¿Necesita que la lista se ordene en su lugar, o simplemente una secuencia ordenada de los contenidos de la lista? Este último es más fácil:

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

Para ordenar en su lugar, necesitaría una IComparer<Person>o una Comparison<Person>. Para eso, es posible que desee considerar ProjectionCompareren MiscUtil .

(Sé que sigo sacando MiscUtil, simplemente sigue siendo relevante ...)

Jon Skeet
fuente
1
Esto funcionó para mí, pero solo después de haber agregado ".ToList ()": contemporariesOrderedByBirthYear = contemporaries.OrderBy (contemp => contemp.BirthYear) .ToList ();
B. Clay Shannon
2
@ B.ClayShannon: Bueno, necesitas eso si quieres un List<T>, pero no lo necesitas si solo quieres iterar.
Jon Skeet
23

puedes usar linq :) usando:

System.linq;
var newList = people.OrderBy(x=>x.Name).ToList();
vampiro203
fuente
23
people.OrderBy(person => person.lastname).ToList();
Danimal
fuente
17
Bueno, eso todavía no captura el resultado: necesitaría una "Lista <Person> people =" en el lado izquierdo ...
Marc Gravell
8
Esta respuesta demuestra el error más común cuando se usa LINQ: métodos como OrderBy no modificar la lista, sino que devuelven una nueva "colección" (generalmente diferida IEnumerable<T>) que debe asignarse a algo.
Alexei Levenkov
2
@AlexeiLevenkov, ¿cómo sabe que este es el error más común al usar 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
fuente
5

Para mí, esta útil guía ficticia - Ordenar en lista genérica - funcionó. Le ayuda a comprender 4 formas (sobrecargas) de hacer este trabajo con explicaciones muy completas y claras y ejemplos simples

  • List.Sort ()
  • List.Sort (Comparación genérica)
  • List.Sort (Generic IComparer)
  • List.Sort (Int32, Int32, Generic IComparer)
Iman
fuente
5

Puede usar este fragmento de código:

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

donde New1esta a List<Employee>.

EmpListes variable de a List<Employee>.

zes una variable de Employeetipo

AnshuMan SrivAstav
fuente
AnshuMan, no hay nada como un vartipo. New1es List<Employee>y zes Employee.
nawfal
5

También puedes usar

model.People = model.People.OrderBy(x => x.Name).ToList();
rosselder83
fuente
44
Si bien este ejemplo de código puede responder la pregunta, carece de explicación. Tal como está ahora, no agrega ningún valor y soporta el cambio de ser rechazado / eliminado. Agregue alguna explicación de lo que hace y por qué es una solución para el problema del OP.
oɔɯǝɹ
0

Este es un clasificador genérico. Llamado con el interruptor de abajo.

dvm.PagePermissions es una propiedad en mi ViewModel de tipo Lista T en este caso T es una clase de modelo EF6 llamada page_permission.

dvm.UserNameSortDir es una propiedad de cadena en el modelo de vista que contiene la siguiente dirección de clasificación. El que se usa actaully en la 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;
    }
howserss
fuente
1
Creo que esto es demasiado complicado. Como puede ver en las otras respuestas, todo se puede hacer en una sola línea (no necesariamente significa que hacerlo en una sola línea es bueno, pero no tengo la ventaja de hacerlo así)
jalgames
Esto es para la clasificación de múltiples columnas usando AngularJS. Es esencialmente la clasificación de una sola línea, pero también establece la variable de dirección de clasificación. Realmente no es tan complejo si lo miras de cerca. Supongo que la función Ordenar es un poco intimidante con todas las cosas genéricas, pero si eliminé esa definición, es una llamada de Clasificación de 1 línea.
Howserss
Demasiado complicado para lo que solicitó el Op. Sin embargo, es una buena solución para un problema diferente.
lanza el