按对象属性之一的值对对象列表进行排序,其中只有一个值是感兴趣的
Posted
技术标签:
【中文标题】按对象属性之一的值对对象列表进行排序,其中只有一个值是感兴趣的【英文标题】:Sort a list of objects by the value of one of their properties, where only one value is of interest 【发布时间】:2021-07-28 22:59:46 【问题描述】:我有一个较大对象的列表,我想根据对象的某个属性的值对其进行排序。
但是,我只关心那些具有该属性的单个给定值的那些位于顶部 - 所有其他值,我不关心它们的顺序。例如,如果我有:
public class MyBigObject
public string Colour;
public string ImportantProperty;
现在,想象一下我有这些:
var a = new MyBigObject("red", "P2")
var b = new MyBigObject("red", "P1")
var c = new MyBigObject("red", "P3")
var d = new MyBigObject("yellow", "P99")
var e = new MyBigObject("yellow", "P3")
我希望它们按颜色排序,然后按 ImportProperty 排序,其中“P3”是我感兴趣的唯一值,我希望在排序列表中排在第一位:
ListOfThoseObjects.OrderBy(c => c.Colour).ThenBy(x => x.???? where "P3" is the most important)
需要让步:
c (red / P3)
a (red / P2)
b (red / P1)
e (yellow / P3)
d (yellow / P99)
我希望能够做到这一点,而不必列出 ImportantProperty 可以是的所有可能值,因为有很多值并且它们可能会超出我的控制范围。我只知道 P3 在排序方面是最重要的。
感谢您的帮助!
【问题讨论】:
.OrderBy(c => c.Colour).ThenBy(x => x.ImportantProperty != "P3");
【参考方案1】:
您可以只使用三元对 0 或 1 求值:
ListOfThoseObjects
.OrderBy(c => c.Colour)
.ThenBy(x => x.ImportantProperty is "P3" ? 0 : 1);
【讨论】:
这么简单,太棒了——非常感谢! 不起作用:“我所关心的是那些具有该属性的单个给定值的人位于顶部”。首先按颜色排序,重要属性的优先级较低,可能排在最后 @TimSchmelter 是的,我推断在示例中也需要按颜色排序。 @TimSchmelter:OP 特别希望 子排序,而不是主排序,来支持 P3。从问题:“我希望它们按颜色排序,然后按重要属性,其中“P3”是我感兴趣的唯一值” @TimSchmelter:看示例数据。 P3 不在列表顶部,它们位于列表中每个颜色组 的顶部。yellow / P3
在red / [any]
之后和yellow / [any]
之前。在几个方面(解释、演示数据和代码示例),很明显按颜色排序是第一位的。您一开始就被一个模棱两可的短语所吸引,并跳过了问题的实质。【参考方案2】:
但是,我只关心那些具有单一给定值的 该属性位于顶部-所有其他值,我不在乎 关于他们的订单
那不是真的。您也是按颜色订购的,所以您似乎想先按该重要属性订购,然后按颜色订购:
var conditionalOrder = ListOfThoseObjects
.OrderBy(x => x.ImportantProperty == "P3" ? 0 : 1)
.ThenBy(x => x.Colour);
【讨论】:
是的,这是真的——在现实生活中我还有更多的东西要排序——但是 ? 0 : 1 正是我所需要的。非常感谢!【参考方案3】:您可以通过bool
自己订购。但是请注意,false < true
。因此,如果您希望带有ImportantProperty == "P3"
的项目位于顶部,请将其设置为
var result = ListOfThoseObjects
.OrderBy(x => x.ImportantProperty != "P3")
.ThenBy(c => c.Colour)
【讨论】:
有趣的一个,我不知道你能做到这一点。【参考方案4】:请务必注意,OrderBy
(以及扩展为 ThenBy
)根据其接收到的值执行排序。该值不一定来自您的对象。例如:
var rand = new Random();
myItems = myItems.OrderBy(item => rand.Next());
这有效地打乱了项目。请注意值 (rand.Next()
) 与 item
完全无关。
在您的情况下,您希望有一个自定义方法,该方法根据某事物是否为 P3
返回特定值。
所以,要做到这一点非常简单:
public int MyCustomOrdering(MyBigObject obj)
if(obj.ImportantProperty == "P3")
return 0;
else
return 1;
然后你可以这样做:
myList = myList.OrderBy(item => MyCustomOrdering(item));
或者,如果您愿意,在这个特定的简单示例中,您可以将所有内容浓缩为:
myList = myList.OrderBy(item => obj.ImportantProperty == "P3" ? 0 : 1);
但对于更复杂的评估,建议将其抽象为一种方法以保持可读性。
【讨论】:
很好的答案 - 非常感谢以上是关于按对象属性之一的值对对象列表进行排序,其中只有一个值是感兴趣的的主要内容,如果未能解决你的问题,请参考以下文章