自定义IComparer for List(排序)的问题 - c#

时间:2009-07-04 17:17:39

标签: c# list sorting ilist icomparer

任何人都可以提供帮助,我在排序方面遇到问题,我认为我对它进行了排序,但似乎无法正常工作。

我有一个存储以下值的列表

8,6,10,11,7

我还有另一个List(我班上的附件,它有一个名为accessoryId的属性,当前类的顺序是id,当前是6,7,8,10,11)

因此我需要将它们从6,7,8,10,11排序到从简单列表中使用的顺序,即8,6,10,11,7

我有我的icomparable(见下文),我这样打电话 - 它确实输入但是出了点问题,因为列表仍然有我所有的课程,但仍然是6,7,8,10,11的顺序< / p>

   // accesories is the IList<Accessories> (hence why i am use ToList)
   // and sortOrder is the simple int list list<int>
   accesories.ToList().Sort(new ItemTpComparer(sortOrder));  

class ItemTpComparer : IComparer<Accessories>
{
    private IList<int> otherList;

    public ItemTpComparer(IList<int> otherList)
    {
        this.otherList = otherList;
    }

    #region IComparer<Accessories> Members

    public int Compare(Accessories x, Accessories y)
    {

        if (otherList.IndexOf(x.AccessoryId) > otherList.IndexOf(y.AccessoryId))
            return 1;

        else if (otherList.IndexOf(x.AccessoryId) < otherList.IndexOf(y.AccessoryId))
            return -1;
        else
            return 0;

        // tried below also didn't work
        //return otherList.IndexOf(x.AccessoryId) - otherList.IndexOf(y.AccessoryId);

2 个答案:

答案 0 :(得分:9)

比较器是正确的(即使是注释的单行版本)。问题是ToList()创建了一个新的List,其中包含IEnumerable<T>对象中的元素副本,所以基本上,您正在创建一个新列表,对其进行排序并将其丢弃。

var sortedList = accesories.ToList();
sortedList.Sort(new ItemTpComparer(sortOrder)); 

我建议替换为:

var sortedList = accessories.OrderBy(sortOrder.IndexOf).ToList();
通过这种方式,不需要比较器实现。您也可以轻松按降序排序:

var sortedList = accessories.OrderByDescending(sortOrder.IndexOf).ToList();

如果对象确实是List<Accessories>,您还可以对其进行排序:

((List<Accessories>)accessories).Sort(new ItemTpComparer(sortOrder));

答案 1 :(得分:1)

Mehrdad向您展示了为什么列表没有排序。我想解决比较器的性能问题,以及排序项比排序项更少的问题。

在列表上使用IndexOf来定位索引是非常低效的。我必须遍历列表中的项目以找到正确的项目。使用字典作为查找,这样您只需循环遍历项目一次:

class ItemTpComparer : IComparer<Accessories> {

   private Dictionary<int, int> index;

   public ItemTpComparer(IList<int> otherList) {
      index = new Dictionary<int, int>();
      for (int i = 0; i < otherList.Count; i++) {
         index.Add(otherList[i], i);
      }
   }

   public int Compare(Accessories x, Accessories y) {
      return index[x.AccessoryId].CompareTo(index[y.AccessoryId]);
   }

}

如果要允许排序的值列表短于要排序的项目列表,请检查字典中是否存在该值:

   public int Compare(Accessories x, Accessories y) {
      int xIndex, yIndex;
      if (!index.TryGetValue(x.AccessoryId, out xIndex)) xIndex = int.MaxValue;
      if (!index.TryGetValue(y.AccessoryId, out yIndex)) yIndex = int.MaxValue;
      return xIndex.CompareTo(yIndex);
   }