简体   繁体   English

C#-如何按linq排序列表字符串号?

[英]C# - How to sort list string number by linq?

I have a list, each element in the list is a string that contains date and integer in specific format: yyyyMMdd_number. 我有一个列表,列表中的每个元素都是一个字符串,其中包含日期和特定格式的整数:yyyyMMdd_number。

List<string> listStr = new List<string> { "20170822_10", "20170821_1", "20170823_4", "20170821_10", "20170822_11", "20170822_5",
                                          "20170822_2", "20170821_3", "20170823_6", "20170823_21", "20170823_20", "20170823_2"};

When use method listStr.Sort(); 使用方法listStr.Sort();

Result as below: 结果如下:

20170821_1
20170821_10
20170821_3
20170822_10
20170822_11
20170822_2
20170822_5
20170823_2
20170823_20
20170823_21
20170823_4
20170823_6

Expected Output: 预期产量:

20170821_1
20170821_3
20170821_10
20170822_2
20170822_5
20170822_10
20170822_11
20170823_2
20170823_4
20170823_6
20170823_20
20170823_21

The way: i think every string(day_number) will split with an underline, then compare and sort by number. 方式:我认为每个字符串(day_number)将用下划线分隔,然后进行比较并按数字排序。 But please suggest me LINQ solution or better way to sort in this case. 但在这种情况下,请向我建议LINQ解决方案或更好的排序方法。

Since the dates are in the format that can be ordered lexicographically, you could sort by the date prefix using string ordering, and resolve ties by parsing the integer: 由于日期采用可按字典顺序排序的格式,因此您可以使用字符串排序方式按日期前缀排序,并通过解析整数来解析联系:

var sorted = listStr
    .OrderBy(s => s.Split('_')[0])
    .ThenBy(s => int.Parse(s.Split('_')[1]));

Demo. 演示

I imagine any numeric ordering would first require converting the value to a numeric type. 我想象任何数字排序都将首先需要将值转换为数字类型。 So you could split on the underscore, sort by the first value, then by the second value. 因此,您可以对下划线进行分割,按第一个值排序,然后按第二个值排序。 Something like this: 像这样:

list.OrderBy(x => x.Split('_')[0]).ThenBy(x => int.Parse(x.Split('_')[1]))

You could improve this, if necessary, by creating a class which takes the string representation on its constructor and provides the numeric representations (and the original string representation) as properties. 如有必要,您可以通过创建一个类,该类在其构造函数上使用字符串表示形式并提供数字表示形式(和原始字符串表示形式)作为属性来改进此功能。 Then .Select() into a list of that class and sort. 然后.Select()进入该类的列表并进行排序。 That class could internally do type checking, range checking, etc. 该类可以在内部进行类型检查,范围检查等。

The answers above are much easier to follow / understand, but purely as an alternative for academic interest, you could do the following: 上面的答案更容易理解/理解,但是纯粹出于学术兴趣的考虑,您可以执行以下操作:

var sorted = listStr.OrderBy(x => Convert.ToInt32(x.Split('_')[0])*100 + Convert.ToInt32(x.Split('_')[1]));

It works on the premise that the suffix part after the underscore is going to be less than 100, and turns the two elements of the string into an integer with the relative 'magnitude' preserved, that can then be sorted. 它的工作前提是,下划线后的后缀部分将小于100,并将字符串的两个元素转换为保留相对“大小”的整数,然后可以对其进行排序。

The other two methods are much, much easier to follow, but one thing going for my alternative is that it only needs to sort once, so would be a bit faster (although I doubt it is going to matter for any real-world scenario). 其他两种方法非常容易上手,但我的另一选择是它只需排序一次,因此速度会更快一些(尽管我怀疑这对任何实际情况都很重要) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM