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(???? => ?????)
Développeur SaaS
la source

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
Marc Gravell
la source
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 ...)

Jon Skeet
la source
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();
vampire203
la source
23
people.OrderBy(person => person.lastname).ToList();
Danimal
la source
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();
        }
    }
}
Bruno
la source
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)
Iman
la source
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 SrivAstav
la source
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();
rosselder83
la source
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;
    }
howserss
la source
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