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()
执行稳定排序。
假设我有一个列表,所有元素都有一个顺序 属性 除了 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()
执行稳定排序。