代码之家  ›  专栏  ›  技术社区  ›  user215675

C-使用扩展方法排序

  •  10
  • user215675  · 技术社区  · 16 年前

    我想整理一份名单

    List<Person> persons=new List<Person>();
    persons.Add(new Person("Jon","Bernald",45000.89));
    persons.Add(new Person("Mark","Drake",346.89)); 
    persons.Add(new Person("Bill","Watts",456.899));
    

    基于

    public enum CompareOptions
     {
        ByFirstName,
        ByLastName,
        BySalary
     }
    
     public enum SortOrder
     {
       Ascending,
       Descending
     }
    

    使用lambda表达式排序的方法是什么?

        public static List<Person> SortPeople(this List<Person> lst, 
       CompareOptions opt1,SortOrder ord)
    
            {
               lst.Sort((p,op1,op2)=>{ how to apply lambda expression here});
            }
    
    4 回复  |  直到 16 年前
        1
  •  9
  •   JaredPar    16 年前

    似乎您正在尝试对调用Sort方法 List<T> 这需要一个 Comparison<T> 代表。这需要一些工作,因为您首先必须定义一个兼容的比较函数。

    第一步是根据 CompareOptions 价值

    private static Comparison<Person> Create(CompareOptions opt) {
      switch (opt) {
        case CompareOptions.ByFirstName: (x,y) => x.FirstName.CompareTo(y.FirstName);
        case CompareOptions.ByLastName: (x,y) => x.LastName.CompareTo(y.LastName);
        case CompareOptions.BySalary: (x,y) => x.Salary - y.Salary;
        default: throw new Exception();
      }
    }
    

    默认情况下,此函数将按升序排序。如果您想让它下降,只需求该值的负。因此,现在可以通过以下方式编写排序

    public static List<Person> SortPeople(
       this List<Person> list, 
       CompareOptions opt1,
       SortOrder ord) )
       var original = Create(opt1);
       var comp = original;
       if( ord == SortOrder.Descending ) {
         comp = (x,y) => -(orig(x,y));
       }
       list.Sort(comp);
    }
    

    编辑

    在lambda中100%完成的版本

    public static List<Person> SortPeople(
       this List<Person> list, 
       CompareOptions opt1,
       SortOrder ord) )
    
       list.Sort( (x,y) => {
         int comp = 0;
         switch (opt) {
           case CompareOptions.ByFirstName: comp = x.FirstName.CompareTo(y.FirstName);
           case CompareOptions.ByLastName: comp = x.LastName.CompareTo(y.LastName);
           case CompareOptions.BySalary: comp = x.Salary.CompareTo(y.Salary);
           default: throw new Exception();
         }
         if ( ord == SortOrder.Descending ) {
           comp = -comp;
         }
         return comp;
       });
    }
    
        2
  •  6
  •   Gabe Moothart    16 年前

    你真的需要这些枚举吗?我不认为将搜索逻辑封装在方法中比仅使用LINQ方法更清晰或更干燥:

    persons.OrderBy( p => p.FirstName );
    persons.OrderByDescending( p => p.Salary);
    

    等。

        3
  •  3
  •   Reed Copsey    16 年前

    要使其在lambda中工作,表达式需要形成 Comparison<T> 签名。这需要2个“人”实例。你可以这样做:

    public static void SortPeople(
        this List<Person> lst, CompareOptions opt1,SortOrder ord)
    {
        lst.Sort((left, right) => 
                 {
                     int result;
                     // left and right are the two Person instances
                     if (opt1 == CompareOptions.Salary)
                     {
                         result = left.Salary.CompareTo(right.Salary);
                     }
                     else
                     {
                         string compStr1, compStr2;
                         if (opt1 == CompareOptions.FirstName)
                         {
                              compStr1 = left.FirstName;
                              compStr2 = right.FirstName;
                         }
                         else
                         {
                              compStr1 = left.LastName;
                              compStr2 = right.LastName;
                         }
                         result = compStr1.CompareTo(compStr2);
                     }
                     if (ord == SortOrder.Descending)
                         result *= -1;
                     return result;
                 });
    }
    
        4
  •  2
  •   Klaus Byskov Pedersen    16 年前
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication2
    {
         class Program
        {
        static void Main(string[] args)
        {
            List<Person> persons = new List<Person>(); 
            persons.Add(new Person("Jon", "Bernald", 45000.89)); 
            persons.Add(new Person("Mark", "Drake", 346.89)); 
            persons.Add(new Person("Bill", "Watts", 456.899));
    
            persons.SortPeople(CompareOptions.ByFirstName, SortOrder.Ascending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            persons.SortPeople(CompareOptions.ByFirstName, SortOrder.Descending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            persons.SortPeople(CompareOptions.ByLastName, SortOrder.Ascending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            persons.SortPeople(CompareOptions.ByLastName, SortOrder.Descending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            persons.SortPeople(CompareOptions.BySalary, SortOrder.Ascending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            persons.SortPeople(CompareOptions.BySalary, SortOrder.Descending);
    
            persons.ForEach(p => Console.WriteLine(p.ToString()));
    
            Console.ReadLine();
        }
    }
    
    public static class Extensions
    {
        public static void SortPeople(this List<Person> lst, CompareOptions opt1,SortOrder ord){
            lst.Sort((Person p1, Person p2) => 
                {
                    switch (opt1)
                    {
                        case CompareOptions.ByFirstName:
                            return ord == SortOrder.Ascending ? p1.FirstName.CompareTo(p2.FirstName) : p2.FirstName.CompareTo(p1.FirstName);
                        case CompareOptions.ByLastName:
                            return ord == SortOrder.Ascending ? p1.LastName.CompareTo(p2.LastName) : p2.LastName.CompareTo(p1.LastName);
                        case CompareOptions.BySalary:
                            return ord == SortOrder.Ascending ? p1.Salary.CompareTo(p2.Salary) : p2.Salary.CompareTo(p1.Salary);
                        default:
                            return 0;
                    }
                });
        }
    }
    
    public class Person
    {
        public double Salary { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        public Person(string first, string last, double salary)
        {
            this.Salary = salary;
            this.FirstName = first;
            this.LastName = last;
        }
    
        public override string ToString()
        {
            return string.Format("{0} {1} has a salary of {2}", this.FirstName, this.LastName, this.Salary);
        }
    }
    
    public enum CompareOptions { ByFirstName, ByLastName, BySalary }
    public enum SortOrder { Ascending, Descending }
    

    }