Liste <T> OrdrePar ordre alphabétique


443

J'utilise C # sur Framework 3.5. Je cherche à trier rapidement un générique List<T>. Pour cet exemple, disons que j'ai une liste d'un Persontype avec une propriété de nom. Comment trier cette liste à l'aide d'une expression lambda?

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

Réponses:


696

Si vous voulez dire un tri sur place (c'est-à-dire que la liste est mise à jour):

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

Si vous voulez dire une nouvelle liste:

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

2
Je crois que le premier veut être people.Sort ((x, y) => string.Compare (x.LastName, y.LastName) <0);
James Curran

36
@James: Je ne pense pas. La comparaison <T> renvoie int, pas bool.
Jon Skeet

2
Je me demande si vous voulez commander par nom et prénom ... que devez-vous écrire?
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

Avez-vous besoin que la liste soit triée sur place ou simplement une séquence ordonnée du contenu de la liste? Ce dernier est plus simple:

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

Pour trier sur place, vous auriez besoin d'un IComparer<Person>ou d'un Comparison<Person>. Pour cela, vous voudrez peut-être considérer ProjectionComparerdans MiscUtil .

(Je sais que je continue à apporter MiscUtil - ça continue d'être pertinent ...)


1
Cela a fonctionné pour moi, mais seulement après avoir ajouté ".ToList ()": contemporariesOrderedByBirthYear = contemporaries.OrderBy (contemp => contemp.BirthYear) .ToList ();
B. Clay Shannon

2
@ B.ClayShannon: Eh bien, vous en avez besoin si vous en voulez List<T>, mais vous n'en avez pas besoin si vous voulez simplement répéter.
Jon Skeet

23

vous pouvez utiliser linq :) en utilisant:

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

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

17
Eh bien, cela ne capture toujours pas le résultat - vous auriez besoin d'une "List <Person> people =" sur le côté gauche ...
Marc Gravell

8
Cette réponse montre l'erreur la plus courante lors de l'utilisation de LINQ - des méthodes comme OrderBy ne modifient pas la liste, mais renvoient plutôt une nouvelle "collection" (généralement paresseuse IEnumerable<T>) qui doit être affectée à quelque chose.
Alexei Levenkov

2
@AlexeiLevenkov comment savez-vous que c'est l'erreur la plus courante lors de l'utilisation de 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

pour moi, ce guide factice utile - Tri dans la liste générique - a fonctionné. il vous aide à comprendre 4 façons (surcharges) de faire ce travail avec des explications très complètes et claires et des exemples simples

  • List.Sort ()
  • List.Sort (comparaison générique)
  • List.Sort (IComparer générique)
  • List.Sort (Int32, Int32, IComparer générique)

5

Vous pouvez utiliser cet extrait de code:

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

New1est a List<Employee>.

EmpListest variable de a List<Employee>.

zest une variable de Employeetype.


AnshuMan, il n'y a rien de tel qu'un vartype. New1est List<Employee>et zest Employee.
nawfal

5

Vous pouvez aussi utiliser

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

4
Bien que cet exemple de code puisse répondre à la question, il manque d'explication. Dans l'état actuel des choses, il n'ajoute aucune valeur et résiste au changement d'être voté / supprimé. Veuillez ajouter quelques explications sur ce que cela fait et pourquoi c'est une solution au problème du PO.
2015

0

Il s'agit d'un trieur générique. Appelé avec l'interrupteur ci-dessous.

dvm.PagePermissions est une propriété sur mon ViewModel de type List T dans ce cas T est une classe de modèle EF6 appelée page_permission.

dvm.UserNameSortDir est une propriété de chaîne sur le modèle de vue qui contient la direction de tri suivante. Celui qui est effectivement utilisé dans la vue.

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
Je pense que c'est beaucoup trop compliqué. Comme vous pouvez le voir dans les autres réponses, tout peut être fait sur une seule ligne (cela ne signifie pas nécessairement que le faire sur une seule ligne est bon, mais je n'ai pas l'avantage de le faire comme ça)
jalgames

C'est pour le tri multi-colonnes en utilisant AngularJS. Il s'agit essentiellement du tri sur une seule ligne, mais il définit également la variable de diretion de tri. Ce n'est vraiment pas si complexe si vous regardez de près. Je suppose que la fonction Sort est un peu intimidante avec tous les trucs génériques mais si je retire cette définition, c'est un appel Sort sur 1 ligne.
howserss

Trop compliqué pour ce que l'Op a demandé. C'est cependant une bonne solution pour un problème différent.
roule le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.