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

使用Linq的列表顺序与排序不同

  •  3
  • Nap  · 技术社区  · 14 年前

    假设列表包含4个ComputeItem 它们的A都设为1,B,C,D都设为0。

    案例1:

    ItemList =
        ItemList
            .OrderByDescending(m => m.A)
            .ThenBy(m => m.B)
            .ThenBy(m => m.C)
            .ThenBy(m => m.D)
            .ToList<ComputeItem>();
    

    案例2:

    ItemList.Sort(
        delegate(ComputeItem item1, ComputeItem item2)
        {
            if (item1.A == item2.A)
            {
                if (item1.B == item2.B)
                {
                    if (item1.C == item2.C)
                    {
                        return item1.D - item2.D;
                    }
                    else
                    {
                        return item1.C - item2.C;
                    }
                }
                else
                {
                    return item1.B - item2.B;
                }
            }
            else
            {
                return item2.A - item1.A;
            }
        }
    );
    



    原始顺序[1,2,3,4]

    案例2新订单[3,4,1,2]

    3 回复  |  直到 14 年前
        1
  •  12
  •   Dan Tao    14 年前

    使用的排序算法 OrderBy OrderByDescending , ThenBy ThenByDescending 是一个 stable QuickSort . 从 MSDN documentation

    此方法执行稳定排序; 元素的顺序是相等的 被保存了下来。

    List<T>.Sort 使用快速排序的不稳定版本,它不一定保留相等元素的原始顺序。再一次,从 MSDN documentation :

    此方法使用 Array.Sort ,其中 使用快速排序算法。这个 实现执行不稳定的 平等,他们的顺序可能不一样 保存。

    这就解释了你所看到的差异。显然,这两种方法的最终结果都是按照比较机制指定的方式对项目进行排序。这只是 出现未指定的 列表<T>。排序 .

    不稳定的 分类 排序。我很难想象这对你来说是一个突破性的改变(什么样的软件

        2
  •  3
  •   to StackOverflow    14 年前

    我想拉胡尔已经一针见血了。 就我个人而言,我认为以下内容更适合您的案例2:

    int result;
    
    // Sort by A descending => invert the sign of the result
    result = - item1.A.CompareTo(item2.A);
    if (result != 0) return result;
    
    // then by B ascending
    result = item1.B.CompareTo(item2.B);
    if (result != 0) return result;
    
    // then by C ascending
    result = item1.C.CompareTo(item2.C);
    if (result != 0) return result;
    
    // then by D ascending
    result = item1.D.CompareTo(item2.D);
    if (result != 0) return result;
    
    // ... add other comparisons here if you ever need to in the future
    
    return result;
    
        3
  •  2
  •   Rahul    14 年前

    是这样吗?

    return item2.A - item1.A;

    还是应该

    return item1.A - item2.A;