简体   繁体   English

如何对数字字符串列表进行排序? 最好使用LINQ

[英]How can I sort a list of numerical strings? Preferably using LINQ

I have a string in below manner:- 我有一个以下方式的字符串: -

string[] things = new string[] { "1", "10", "2", "1_1", "2_1","3_1" };

The desired output is: 所需的输出是:

"1",
"1_1",
"2",
"2_1",
"3_1",
"10",

How I can achieve this using LINQ? 我如何使用LINQ实现这一目标?

Yes there is, you can split each part by _ and convert the first string part to an integer. 是的,你可以用_分割每个部分,并将第一个字符串部分转换为整数。 When sorting afterwards this will ensure that 10 is not before 2 . 在事后排序时,这将确保10不在2之前。 Then in the second step you order it according to the last number 然后在第二步中根据最后一个数字进行订购

string[] things = new string[] { "5_3", "5_2", "1", "10", "2", "1_1", "2_1", "1_2", "3_1" };

string[] ordered = things.OrderBy(x=>Convert.ToInt32(x.Split('_').First())).                       
                           ThenBy(x=>Convert.ToInt32(x.Split('_').Last())).ToArray();

Output: 输出:

在此输入图像描述

EDIT: Here is the link to the documentation of ThenBy for the sake of informativity ;) 编辑:这是为了提供信息,可以链接到ThenBy文档 ;)

What about this? 那这个呢?

string[] strings = new string[] { "1", "10", "2", "1_1", "2_1", "3_1" };

var ordered = from str in strings
                let weight = double.Parse(str.Replace("_", CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator))
                let pair = new { Weight = weight, OriginalString = str }
                orderby pair.Weight
                select pair.OriginalString;

This will give you the desired output: 这将为您提供所需的输出:

string[] things = new string[] { "1", "10", "2", "1_1", "2_1", "3_1" };
var list =  from row in things select Decimal.Parse(row.Replace("_",CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator));
list = list.OrderBy(d=> d).ToList();
var StringList = from row in list select row.ToString("0.#").Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, "_");

You can use one of the overloads of OrderBy that allows you to create your own key and maybe specify your own comparer. 您可以使用OrderBy中的一个重载,它允许您创建自己的密钥,并可能指定您自己的比较器。 It looks like you want to treat _ as a decimal separator. 看起来您想将_视为小数分隔符。

One quick & dirty way would be to replace _ with the decimal separator, eg : 一种快速而肮脏的方法是用小数分隔符替换_ ,例如:

var decSeparator=CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

var orderedThings=things.OrderBy(thing=>double.Parse( thing.Replace("_",decSeparator)) )
                        .ToArray();

This is quick & dirty because it assumes _ appears only once. 这是快速和脏的,因为它假设_只出现一次。 If _ appeared multiple times, the replaced string wouldn't be a valid number 如果_多次出现,则替换后的字符串将不是有效数字

If that format is strict you could parse to Version and order by that: 如果该格式是严格的,您可以解析为Version并按顺序排序:

string[] orderedThings = things
   .Select(t => new { Thing = t, Numbers = (t + "_0").Split('_') })
   .Where(x => x.Numbers.All(s => s.All(char.IsDigit)))
   .Select(x => new { x.Thing, VersionStr = String.Join(".",x.Numbers.Take(4)) })
   .OrderBy(x => new Version(x.VersionStr))
   .ThenBy(x => x.Thing)
   .Select(x => x.Thing)
   .ToArray();

The t + "_0" trick was necessary to ensure that also single digits can be parsed. t + "_0"技巧是必要的,以确保也可以解析单个数字。 A version needs at least a major and aminor part. 一个版本至少需要一个主要部分和一个部分。 This "works" also if there are more than 4 tokens(major, minor, build, and revision). 如果有超过4个令牌(主要,次要,构建和修订),这也“有效”。 Then only the first 4 are taken to initialize the Version instance. 然后只有前4个用于初始化Version实例。

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

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