我有一个列表,列表中的每个元素都是一个字符串,其中包含特定格式的日期和整数: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"};
使用方法listStr.Sort();
结果如下:
20170821_1 20170821_10 20170821_3 20170822_10 20170822_11 20170822_2 20170822_5 20170823_2 20170823_20 20170823_21 20170823_4 20170823_6
预期输出:
20170821_1 20170821_3 20170821_10 20170822_2 20170822_5 20170822_10 20170822_11 20170823_2 20170823_4 20170823_6 20170823_20 20170823_21
方式:我认为每个字符串(day_number)将以下划线分割,然后按数字进行比较和排序。 但在这种情况下,请建议我使用LINQ解决方案或更好的方法进行排序。
答案 0 :(得分:9)
由于日期的格式可以按字典顺序排序,您可以使用字符串排序按日期前缀排序,并通过解析整数来解析关系:
var sorted = listStr
.OrderBy(s => s.Split('_')[0])
.ThenBy(s => int.Parse(s.Split('_')[1]));
答案 1 :(得分:2)
我想任何数字排序都首先需要将值转换为数字类型。因此,您可以拆分下划线,按第一个值排序,然后按第二个值排序。像这样:
list.OrderBy(x => x.Split('_')[0]).ThenBy(x => int.Parse(x.Split('_')[1]))
如果需要,您可以通过创建一个在其构造函数中获取字符串表示形式的类并将数字表示形式(以及原始字符串表示形式)作为属性来改进。然后.Select()
进入该类的列表并排序。该类可以在内部进行类型检查,范围检查等。
答案 2 :(得分:1)
上述答案更易于理解,但纯粹作为学术兴趣的替代方案,您可以执行以下操作:
var sorted = listStr.OrderBy(x => Convert.ToInt32(x.Split('_')[0])*100 + Convert.ToInt32(x.Split('_')[1]));
它的前提是下划线后面的后缀部分将小于100,并将字符串的两个元素转换为具有相对大小的整数&#39;保存,然后可以进行分类。
另外两种方法更容易理解,但我可以选择的另一种方法是它只需要排序一次,所以会更快一些(尽管我怀疑这对任何真实的方法都很重要)世界情景)。