1

谁能帮忙,我做排序有问题,我以为我已经排序但似乎没有工作。

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

8,6,10,11,7

我还有另一个列表(我的类中的附件,它有一个名为 accessoryId 的属性,当前类的 id 顺序为 6、7、8、10、11)

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

我有我的 icomparable (见下文),我这样打电话 - 它确实输入但有问题,因为列表仍然包含我的所有课程,但仍按 6、7、8、10、11 的顺序

   // 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);
4

2 回答 2

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));
于 2009-07-04T17:27:24.427 回答
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);
   }
于 2009-07-04T18:32:24.167 回答