300 votes

Tri d'une liste à l'aide de Lambda/Linq to objects

J'ai le nom de "trier par propriété" dans une chaîne de caractères. Je vais devoir utiliser Lambda/Linq pour trier la liste des objets.

Ex:

public class Employee
{
  public string FirstName {set; get;}
  public string LastName {set; get;}
  public DateTime DOB {set; get;}
}


public void Sort(ref List<Employee> list, string sortBy, string sortDirection)
{
  //Example data:
  //sortBy = "FirstName"
  //sortDirection = "ASC" or "DESC"

  var sort = list.

  if (sortBy == "FirstName")
  {
    list = list.OrderBy(x => x.FirstName).toList();    
  }

}
  1. Au lieu d'utiliser un tas de ifs pour vérifier le nom du champ (sortBy), est-il une manière plus propre de faire le tri
  2. Il est en quelque sorte au courant de type de données?

411voto

gls123 Points 2013

Cela peut être fait comme

list.Sort( (emp1,emp2)=>emp1.FirstName.CompareTo(emp2.FirstName) );

L' .NET framework est un moulage de la lambda (emp1,emp2)=>int comme Comparer<Employee>.

Cela a l'avantage d'être fortement typé.

75voto

Samuel Points 21085

Une chose que vous pourriez faire est de changer Sort de sorte qu'il permet d'optimiser l'utilisation des expressions lambda.

public enum SortDirection { Ascending, Descending }
public void Sort<TKey>(ref List<Employee> list,
                       Func<Employee, TKey> sorter, SortDirection direction)
{
  if (direction == SortDirection.Ascending)
    list = list.OrderBy(sorter);
  else
    list = list.OrderByDescending(sorter);
}

Maintenant, vous pouvez spécifier le champ de tri lors de l'appel de l' Sort méthode.

Sort(ref employees, e => e.DOB, SortDirection.Descending);

56voto

tvanfosson Points 268301

Vous pouvez utiliser la Réflexion pour obtenir la valeur de la propriété.

list = list.OrderBy( x => TypeHelper.GetPropertyValue( x, sortBy ) )
           .ToList();

Où TypeHelper possède une méthode statique comme:

public static class TypeHelper
{
    public static object GetPropertyValue( object obj, string name )
    {
        return obj == null ? null : obj.GetType()
                                       .GetProperty( name )
                                       .GetValue( obj, null );
    }
}

Vous pouvez également regarder Dynamique LINQ de la VS2008 Échantillons de la bibliothèque. Vous pouvez utiliser l'interface IEnumerable extension de fonte de la Liste comme un IQueryable et ensuite utiliser le lien Dynamique OrderBy extension.

 list = list.AsQueryable().OrderBy( sortBy + " " + sortDirection );

23voto

Cornel Urian Points 111

Voilà comment j'ai résolu mon problème:

List<User> list = GetAllUsers();  //Private Method

if (!sortAscending)
{
    list = list
           .OrderBy(r => r.GetType().GetProperty(sortBy).GetValue(r,null))
           .ToList();
}
else
{
    list = list
           .OrderByDescending(r => r.GetType().GetProperty(sortBy).GetValue(r,null))
           .ToList();
}

16voto

Rashack Points 3344

La construction de la commande par l'expression peut être lu ici

Sans vergogne volés de la page dans le lien:

// First we define the parameter that we are going to use
// in our OrderBy clause. This is the same as "(person =>"
// in the example above.
var param = Expression.Parameter(typeof(Person), "person");

// Now we'll make our lambda function that returns the
// "DateOfBirth" property by it's name.
var mySortExpression = Expression.Lambda<Func<Person, object>>(Expression.Property(param, "DateOfBirth"), param);

// Now I can sort my people list.
Person[] sortedPeople = people.OrderBy(mySortExpression).ToArray();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X