【问题标题】:Why is my List.Sort method in C# reversing the order of my list?为什么我在 C# 中的 List.Sort 方法颠倒了我的列表顺序?
【发布时间】:2011-02-10 01:59:24
【问题描述】:

我有一个通用列表中的项目列表:

  • A1(排序索引 1)
  • A2(排序索引 2)
  • B1(排序索引 3)
  • B2(排序索引 3)
  • B3(排序索引 3)

它们的比较器采用以下形式:

this.sortIndex.CompareTo(other.sortIndex)

当我对项目列表执行 List.Sort() 时,我得到以下顺序:

  • A1
  • A2
  • B3
  • B2
  • B1

在排序索引的顺序正确的意义上,它显然有效,但我真的不希望它重新排序“B”项。

我可以对比较器进行任何调整来解决这个问题吗?

【问题讨论】:

标签: c# .net sorting icomparable


【解决方案1】:

OrderBy 保留相等项目的顺序:

myList = myList.OrderBy(item => item.SortIndex).ToList();

【讨论】:

    【解决方案2】:

    如果您不希望相等的项目改变位置,则需要使用“stable sort”算法。

    查看“merge sort”以获取稳定排序算法的示例。这是 C# 中的 an implementation

    【讨论】:

      【解决方案3】:

      StableSort()List<T> 的扩展方法是here

      【讨论】:

        【解决方案4】:

        您可以更改比较器以对值进行二次排序:

        if (this.sortIndex.CompareTo(other.sortIndex) == 0) // same sortIndex
        {
           return this.Value.CompareTo(other.Value);
        }
        return 0;
        

        【讨论】:

        • 这与我发布的示例不完全相同吗?
        • @Fiona:不,代码在辅助比较中使用该值,但如果您想使用它,您必须进行一些更正,因为它通过返回零而不是结果。
        • 啊,我明白了。我没有真正要使用的辅助比较(尽管我可以添加一个人工比较,这会很好),我想要保留的列表顺序是基于一个非常复杂的递归函数的输出。
        【解决方案5】:

        排序使用快速排序,在比较相等的情况下不保证原始顺序。

        如果您仍想使用 List.Sort,您可以添加与原始索引的第二个比较,例如:

        int c = this.sortIndex.CompareTo(other.sortIndex);
        if (c == 0)
          c = this.originalIndex.CompareTo(other.originalIndex);
        return c;
        

        否则,您可以使用其他“稳定”算法(例如 LINQ OrderBy)进行排序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-09-05
          • 2021-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多