你能帮帮我吗!我有这样的对象列表:
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 在第一个数据中具有最大权重,在列表末尾为 null。
item.OrderBy(x => x.data == null).ThenByDescending(x => x.data == null ? 0 : x.data.weight);
我假设权重是一个整数,否则根据类型提供默认值。
鉴于您只运送水果,而不是轻量级,您可以将具有null
数据的项目视为权重为 0。或者,只需选择低于可能的有效值的任何值,以便在升序排序时将null
项放在顶部。
你可以这样表达:
var ordered = item.OrderBy(x => x.data == null ? 0 : x.data.weight);
你可以使用这样的东西:(假设 C# 6 或更高版本)
item.OrderBy(x => x.data?.weight ?? int.MinValue);
这利用了新的 C#6 空条件运算符和空合并运算符 - 如果您需要适用于较低版本的 C# 的内容,可以使用三元运算符,如下所示:
item.OrderBy(x => x.data != null ? x.data.weight : int.MinValue);
如果有可能x.data.weight
int.MinValue
,那么你需要做一些类似于你以前做的事情,但第二个linq方法应该使用上面的lambda/s。
您可以通过几种方式执行此操作,一种方法是让一个值使用三元条件运算符替换 null 值,或者过滤掉没有值的项目,并在使用值对对象进行排序后将它们连接到可枚举对象。
通过有条件地为具有 null 的项目提供值
在我看来,这是最好的方法,而且性能更好。您只枚举集合一次,而另一种方法则枚举以确定每个元素是否具有值然后排序,然后检查没有值的项目
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))