C# 对具有已定义 属性 的元素进行就地排序

C# in-place sort on elements that have a defined property

假设我有一个列表,所有元素都有一个顺序 属性 除了 ID 为 4 的元素:

List<Element> elements = new List<Element> {
    new Element {Id = 1, Name = "First", Order = 2}, 
    new Element {Id = 2, Name = "Second", Order = 3}, 
    new Element {Id = 3, Name = "Third", Order = 1}, 
    new Element {Id = 4, Name = "Fourth", Order = null};

我需要根据 order 属性 就地对元素进行排序,但是没有考虑 ID 为 4 的元素,因为它的顺序是 属性 设置为空。

public void ModifyList() { 
   Order(elements);

   return elements; // I want to end up with Element Id:3, 
                    // Element Id:1, Element Id:2 and the last 
                    // one Element with Id:4 (it is returned 
                    //   as the last element as the sort did not apply to it.
}

private static void Order(IList<Element> elements) {
   elements.Sort((x, y) => x.Order.CompareTo(y.Order));
}

我知道我可以先创建一个列表,其中包含具有 属性 顺序的元素,对它们进行排序,然后附加到没有 属性 的列表中,有没有更干净的方法来做到这一点。 (不使用 OrderBy())。

尝试:

foreach(var item in elements.OrderBy( x=> (x.Order is null ? 9999 : x.Order))) {
    System.Console.WriteLine(item.Id);
}

Id 的值也在该范围内时,您当然应该更改 9999...

参见:fiddle

您可以编写自己的比较器以确保 Null 位于末尾:

public sealed class ElementComparer: IComparer<Element>
{
    public int Compare(Element? x, Element? y)
    {
        if (ReferenceEquals(x, y))
            return 0;

        if (ReferenceEquals(null, y))
            return 1;

        if (ReferenceEquals(null, x))
            return -1;

        if (x.Order == null)
            return 1;

        if (y.Order == null)
            return -1;

        return x.Order.Value.CompareTo(y.Order.Value);
    }
}

然后您可以 in-place 对列表中的元素进行排序,如下所示:

 elements.Sort(new ElementComparer());

如果您尝试一下,您会发现它按 .Order 排序,但末尾有任何空值。

需要注意的一点是,List<T>.Sort()是一个不稳定的排序,也就是说排序后,.Order相同的项的顺序](包括空值)未定义。

Enumerable.OrderBy() 执行稳定排序。