item[0].title = apple
item[0].data.weight = 1
item[1].title = lemon
item[1].data = null
item[2].title = melon
item[2].data.weight = 3
我想用空数据按重量对它进行排序(ASC和DESC)。 我试过这样:
item.OrderBy(x => x.data == null).ThenBy(x => x.data.weight); // failed
item.Where(x => x.data != null).OrderBy(x => x.data.weight); // ok, but as result only two records
所以我如何对物品进行分类并获得所有结果。 ASC首先应该是null数据。 DESC首先在列表末尾有最大权重和空值的数据。
答案 0 :(得分:2)
item.OrderBy(x => x.data == null).ThenByDescending(x => x.data == null ? 0 : x.data.weight);
我假设weight是一个int,否则根据类型提供默认值。
答案 1 :(得分:1)
鉴于您只提供水果,而不是光,您可以将null
数据的项目视为权重为0.或者,只需选择低于该值的任何值即可。可能的有效值,以便在按升序排序时将null
项置于顶部。
你可以这样表达:
var ordered = item.OrderBy(x => x.data == null ? 0 : x.data.weight);
答案 2 :(得分:0)
你可以使用这样的东西:(假设C#6或以上)
item.OrderBy(x => x.data?.weight ?? int.MinValue);
这使用了新的C#6 null-conditional和null-coalescing运算符 - 如果你需要在较低版本的C#中使用的东西,你可以使用三元运算符,如下所示:
item.OrderBy(x => x.data != null ? x.data.weight : int.MinValue);
如果您可能x.data.weight
为int.MinValue
,那么您需要做一些类似于之前做过的事情,但第二个linq方法应该使用在lambda / s之上。
答案 3 :(得分:0)
你可以通过几种方式实现这一点,一种方法是使用订单上的三元条件运算符替换空值,或者过滤掉没有值的项,并在排序后将它们连接到可枚举项具有值的对象。
在我看来,这是最好的方式,而且表现更好。您只枚举一次集合,而不是枚举的另一种方法,以确定每个元素是否有一个值然后排序,然后检查没有值的项目
item.OrderBy(x => x.data != null ? x.data.weight : int.MinValue)
有时候这可能是更好的解决方案。例如,如果您想要在缺少要查找的属性时使用不同的方法来排序值,那么就是一个例子。
item.Where(x => x.data != null)
.OrderBy(x => x.data.weight)
.Concat(item.Where(a=>a.data == null))