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

时间:2017-12-20 09:08:01

标签: c# .net linq sorting

我有以下方式的字符串: -

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

所需的输出是:

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

如何使用LINQ实现这一目标?

5 个答案:

答案 0 :(得分:5)

是的,您可以按_拆分每个部分,并将第一个字符串部分转换为整数。在事后排序时,这将确保10不在2之前。然后在第二步中根据最后一个数字

订购
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();

输出:

enter image description here

编辑:以下是为了提供信息而documentation of ThenBy的链接;)

答案 1 :(得分:2)

这个怎么样?

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;

答案 2 :(得分:2)

这将为您提供所需的输出:

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, "_");

答案 3 :(得分:2)

您可以使用OrderBy的一个重载,它允许您创建自己的密钥,并可能指定您自己的比较器。看起来您希望将_视为小数分隔符。

一个快速&脏的方法是用小数分隔符替换_,例如:

var decSeparator=CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;

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

这很快&脏,因为它假设_只出现一次。如果_多次出现,则替换的字符串将不是有效数字

答案 4 :(得分:1)

如果格式严格,您可以解析为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();

t + "_0"技巧是必要的,以确保也可以解析单个数字。一个版本至少需要一个主要部分和一个部分。如果有超过4个令牌(主要,次要,构建和修订),这也“有效”。然后只有前4个用于初始化Version实例。