【问题标题】:How to sort a list of objects with IComparable and IComparer如何使用 IComparable 和 IComparer 对对象列表进行排序
【发布时间】:2015-01-08 05:17:48
【问题描述】:

我正在尝试实现此链接的相同示例,但更关注受抚养孩子的数量。

http://www.codeproject.com/Articles/42839/Sorting-Lists-using-IComparable-and-IComparer-Inte

所以我有 3 名员工,分别是 A:0、B:0、C:2。我想按孩子的数量顺序排列它们。所以我会有 C:2, B:0, A:0

但是我的列表没有被排序。它仍然是 A: 0, B: 0, C: 2

我做错了什么?

我的比较器

public class EmployeeComparer : IComparer<Employee>
{
    public int Compare(Employee x, Employee y)
    {
        this.CompareNumberOfKids(x, y);
    }

    public int CompareNumberOfKids(Employee x, Employee y)
    {
        if (x.NumberOfKids > y.NumberOfKids)
        {
            return -1;
        }
        else if (x.NumberOfKids < y.NumberOfKids)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
}

我的商业实体

public class Employee : IComparable<Employee>
{
    //...//
    Public NumberOfKids { get; set; }

    int IComparable<Employee>.CompareTo(Employee next)
    {
        return new EmployeeComparer().Compare(this, next);
    }

    public override bool Equals(object obj)
    {
        if (obj != null && obj is Emmployee)
        {
            return ((Employee)obj).ID.Equals(this.ID);
        }
        else return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

Aspx.cs

public List<Employee> GetEmployeeSortedList()
{
    List<Employee> list = new List<Employee>();
    list.Add(new Employee() { Name = "A", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "B", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "C", NumberOfKids = 2 } );
    list.Add(new Employee() { Name = "D", NumberOfKids = 1 } );
    list.Add(new Employee() { Name = "E", NumberOfKids = 0 } );
    list.Add(new Employee() { Name = "F", NumberOfKids = 4 } );

    list = list.Take(3).ToList();
    EmployeeComparer comp = new EmployeeComparer();
    list.Sort(comp);
    return list;
}

【问题讨论】:

  • 我刚刚运行了这段代码,它对它进行了正确排序。你确定这是你在做什么?
  • 这段代码对我来说看起来不错,虽然你不需要IComparableIComparer 比较器就足够了。此外,您可以删除 if 语句以支持 x.NumberOfKids.CompareTo(y.NumberOfKids),因为标准 .NET 类型已经实现了 IComparable&lt;T&gt;

标签: c# list sorting icomparable icomparer


【解决方案1】:

首先,如果您的Employee 类使用相同的排序标准实现IComparable&lt;Employee&gt;,则不需要按降序排序的IComparer&lt;Employee&gt;。对于您的Employee 类来说,每次比较都实例化一个新的IComparer&lt;Employee&gt; 效率非常低。

您应该更改您的 Employee 类,使其 CompareTo 看起来像这样:

int CompareTo(Employee next)
{
    return next.NumberOfKids.CompareTo(this.NumberOfKids);
}

然后你可以完全放弃EmployeeComparer 并像这样排序:

list = list.Take(3).ToList();
list.Sort();  // Uses default IComparable for the Employee class
return list;

通常,您使类上的IComparable&lt;T&gt; 实现执行默认排序顺序。对于员工,这可能是员工 ID 或姓氏,名字。 IComparer&lt;T&gt; 实现应该针对其他排序标准。

不过,使用List&lt;T&gt;,您还有另一个选择:使用匿名函数。例如,你可以这样写:

list.Sort((x, y) => y.NumberOfKids.CompareTo(x.NumberOfKids));

this List.Sort overload

或者,您可以完全放弃 IComparer&lt;T&gt;IComparable&lt;T&gt;List.Sort 的整个想法,并使用 LINQ 方式:

var result = list.Take(3).OrderByDescending(x => x.NumberOfKids).ToList();

【讨论】:

【解决方案2】:

这是从msdn得到的另一种方式

using System;
using System.Collections;
namespace ConsoleEnum
{   
   public class car : IComparable
   {      
      // Beginning of nested classes.

      // Nested class to do ascending sort on year property.
      private class sortYearAscendingHelper: IComparer
      {
         int IComparer.Compare(object a, object b)
         {
            car c1=(car)a;
            car c2=(car)b;

            if (c1.year > c2.year)
               return 1;

            if (c1.year < c2.year)
               return -1;

            else
               return 0;
         }
      }

      // Nested class to do descending sort on year property.
      private class sortYearDescendingHelper: IComparer
      {
         int IComparer.Compare(object a, object b)
         {
            car c1=(car)a;
            car c2=(car)b;

            if (c1.year < c2.year)
               return 1;

            if (c1.year > c2.year)
               return -1;

            else
               return 0;
         }
      }

      // Nested class to do descending sort on make property.
      private class sortMakeDescendingHelper: IComparer
      {
         int IComparer.Compare(object a, object b)
         {
            car c1=(car)a;
            car c2=(car)b;
             return String.Compare(c2.make,c1.make);
         }
      }

      // End of nested classes.

      private int year;
      private string make;

      public car(string Make,int Year)
      {
         make=Make;
         year=Year;
      }

      public int Year
      {
         get  {return year;}
         set {year=value;}
      }

      public string Make
      {
         get {return make;}
         set {make=value;}
      }

      // Implement IComparable CompareTo to provide default sort order.
      int IComparable.CompareTo(object obj)
      {
         car c=(car)obj;
         return String.Compare(this.make,c.make);
      }

      // Method to return IComparer object for sort helper.
      public static IComparer sortYearAscending()
      {      
         return (IComparer) new sortYearAscendingHelper();
      }

      // Method to return IComparer object for sort helper.
      public static IComparer sortYearDescending()
      {      
         return (IComparer) new sortYearDescendingHelper();
      }

      // Method to return IComparer object for sort helper.
      public static IComparer sortMakeDescending()
      {      
        return (IComparer) new sortMakeDescendingHelper();
      }

   }
}

这里是如何使用

using System;

namespace ConsoleEnum
{
   class host
   {
      [STAThread]
      static void Main(string[] args)
      {
         // Create an arary of car objects.      
         car[] arrayOfCars= new car[6]
         {
            new car("Ford",1992),
            new car("Fiat",1988),
            new car("Buick",1932),
            new car("Ford",1932),
            new car("Dodge",1999),
            new car("Honda",1977)
         };

         // Write out a header for the output.
         Console.WriteLine("Array - Unsorted\n");

         foreach(car c in arrayOfCars)
            Console.WriteLine(c.Make + "\t\t" + c.Year);

         // Demo IComparable by sorting array with "default" sort order.
         Array.Sort(arrayOfCars);
         Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n");

         foreach(car c in arrayOfCars)
            Console.WriteLine(c.Make + "\t\t" + c.Year);

         // Demo ascending sort of numeric value with IComparer.
         Array.Sort(arrayOfCars,car.sortYearAscending());
         Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n");

         foreach(car c in arrayOfCars)
            Console.WriteLine(c.Make + "\t\t" + c.Year);

         // Demo descending sort of string value with IComparer.
         Array.Sort(arrayOfCars,car.sortMakeDescending());
         Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n");

         foreach(car c in arrayOfCars)
            Console.WriteLine(c.Make + "\t\t" + c.Year);

         // Demo descending sort of numeric value using IComparer.
         Array.Sort(arrayOfCars,car.sortYearDescending());
         Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n");

         foreach(car c in arrayOfCars)
            Console.WriteLine(c.Make + "\t\t" + c.Year);

         Console.ReadLine();
      }
   }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 1970-01-01
    相关资源
    最近更新 更多