按对象属性之一的值对对象列表进行排序,其中只有一个值是感兴趣的

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 / P3red / [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);

但对于更复杂的评估,建议将其抽象为一种方法以保持可读性。

【讨论】:

很好的答案 - 非常感谢

以上是关于按对象属性之一的值对对象列表进行排序,其中只有一个值是感兴趣的的主要内容,如果未能解决你的问题,请参考以下文章

按设置的子对象的值对父对象进行排序

如何按对象中的值对数组进行排序

Android-java-如何按对象内的某个值对对象列表进行排序

在Java中按属性值对对象ArrayList进行排序

按字符串属性值对对象数组进行排序

如何根据属性值对对象列表进行排序