Null值的Linq排序
本文关键字:排序 Linq 值的 Null | 更新日期: 2023-09-27 18:12:47
我有一个类,它有一个字符串属性,有时它可以是null,有时它可以是整数,或者它可以是字符串。
我想在此属性的基础上排序使用LINQ与升序整数值和所有非整数值在后面和空值在最后
如何创建一个LINQ表达式来处理以下场景
例子"1" ,NULL , "34", "6" ,"67",NULL ,"r45","j34" ,"s" to be sorted as
"1" "6" "34" "67" "j34" "r45" "s" NULL NULL
我试过这样做,但不是很完美,答案是
var licenseitems_master = my master list
var firstPart = licenseitems_master.Where(x => !String.IsNullOrEmpty(x.Page) && x.Page.All(char.IsDigit)).OrderBy(x => Convert.ToInt32(x.Page));
var secondPart = licenseitems_master.Where(x => !String.IsNullOrEmpty(x.Page) && !x.Page.All(char.IsDigit)).OrderBy(x => x.Page);
var thirdPart = licenseitems_master.Where(x => String.IsNullOrEmpty(x.Page)).ToList();
var sorted_items = firstPart.Union(secondPart).Union(thirdPart).ToList();
我们可以把它作为一个单一的LINQ表达式吗?
在这种情况下,典型的方法是先按某个优先级表达式排序,然后按其他东西排序(这只对同等优先级生效)。在您的场景中,它可能是这样的:
var sorted_items =
(from x in licenseitems_master
let pageOrder = string.IsNullOrEmpty(x.Page) ? 2 : x.Page.All(char.IsDigit) ? 0 : 1
orderby pageOrder, pageOrder == 0 ? Convert.ToInt32(x.Page) : 0, x.Page
select x).ToList();
你也可以这样做。
First: TryParse to int,并按该值排序(如果无法解析,则将值替换为Int32)。MaxValue,它将把这些值放在末尾)。
第二步:在末尾放null
第三:按"string" value
排序int outValue;
var result = input
.OrderBy(m => Int32.TryParse(m, out outValue)
? outValue
: Int32.MaxValue)
.ThenBy(m => m == null)
.ThenBy(m => m)
.ToList();
以下是使用Linq的一种方法
- 一阶升序null/not null
- 然后按数字升序排序
- 则按升序排序
经List<string>
检验
var input = new List<string>() { "1", null, "34", "6", "67", null, "r45", "j34", "s" };
List<string> result = input.OrderBy(x => x == null)
.ThenBy(x => x != null && x.All(y => char.IsDigit(y)) ? int.Parse(x) : int.MaxValue)
.ThenBy(x => x).ToList();
对于这种情况,我也更喜欢自定义比较器(更容易阅读/维护),但问题是关于Linq
方法
也许你可以使用这种比较器:
public class MyComparer : IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null && y == null) return 0;
if (x == null) return 1;
if (y == null) return -1;
if (x.All(char.IsDigit) && y.All(char.IsDigit))
{
var n1 = Convert.ToInt32(x);
var n2 = Convert.ToInt32(y);
return n1 - n2;
}
return x.CompareTo(y);
}
}
然后像这样使用:
var myComparer = new MyComparer();
var sorted_items = "my master list".OrderBy(x => x.Page, myComparer).ToList();