class ListSort
{
static void Main(string[] args)
{
string[] partNumbers = new string[]
{
"India", "US","UK", "Australia","Germany", "1", "7", "9"
};
var result = partNumbers.OrderBy(x => x).ToList();
}
}
我尝试了上面的代码,并期望得到以下输出:
Australia
Germany
India
UK
US
1
7
9
修改: 数字应按数字排序(1,7,9,70,...),而非数字应始终按词汇顺序排列,即使内部有数字(“A3stralia”,“Australia”,“Germany”)。
答案 0 :(得分:1)
试试这个:
string[] partNumbers = new string[]
{
"India", "US","UK", "Australia","Germany", "1", "7", "9"
};
var result = partNumbers.OrderBy(x => char.IsNumber(x.FirstOrDefault())).ThenBy(x => x).ToList().Dump();
请注意,这仅适用于您的数据是数字或文本,而不是像“U2S”这样的值。如果你需要的话,我也可以改变它以适应这些情况。此外,数字字符串仍然按字符串排序,因此“10”出现在“2”之前。
将A3stralia
和70
添加到列表中时,您希望结果如何?
编辑:更改了新约束:
string[] partNumbers = new string[]
{
"India", "US","UK", "Australia","Germany", "1", "7", "9", "70", "A3stralia"
};
var result =
partNumbers
.Select(x => { int p; bool isNumber = int.TryParse(x, out p); return new { IsNumber = isNumber, NumericValue = isNumber ? p : int.MinValue, StringValue = x }; })
.OrderBy(x => x.IsNumber)
.ThenBy(x => x.NumericValue)
.ThenBy(x => x.StringValue)
.Select(x => x.StringValue)
.ToList();
答案 1 :(得分:1)
如果按字典顺序排列数字部分无关紧要:
var result = partNumbers.OrderBy(s => s.All(Char.IsDigit)).ThenBy(s => s).ToList();
这只是检查所有字符是否都是数字。如果您想要数字,请先使用Enumerable.OrderByDescending
。
如果你想要以数字方式订购数字的答案之一,那么你需要先解析它们:
result = partNumbers
.Select(s => new { s, num = s.TryGetInt() } )
.GroupBy(x => x.num.HasValue) // two groups: one can be parsed to int the other not
.SelectMany (xg =>
{
if (xg.Key) // can be parsed to int, then order by int-value
return xg.OrderBy(x => x.num.Value).Select(x => x.s);
else // can not be parsed to int, order by the string
return xg.OrderBy(x => x.s).Select(x => x.s);
})
.ToList();
我正在使用此扩展程序在LINQ查询中解析strings
到Nullable<int>
:
public static class NumericExtensions
{
public static int? TryGetInt(this string item)
{
int i;
bool success = int.TryParse(item, out i);
return success ? (int?)i : (int?)null;
}
}
答案 2 :(得分:1)
到目前为止,似乎所有的反应大致相同,但都太复杂了。我的尝试:
string[] partNumbers = { "US", "1", "UK", "Australia", "Germany", "70", "9" };
partNumbers.OrderBy(x =>
{
int parseResult;
return int.TryParse(x, out parseResult)
? parseResult
: null as int?;
})
.ThenBy(x => x);
或者,使用提取的辅助方法:
partNumbers.OrderBy(TryParseNullableInt).ThenBy(x => x);
private static int? TryParseNullableInt(string source)
{
int parseResult;
return int.TryParse(x, out parseResult)
? parseResult
: null as int?;
}
答案 3 :(得分:0)
以下解决方案将字符串序列投影到匿名类型{ isNumber, s, value }
,其中包含序列中的当前项,信息是否为项是整数,以及可能的解析结果。然后将新序列分组为两组 - 一组用于数字,一组用于其他字符串。每个组都按照字母顺序排序 - 数字比较,字符串。并且从展平组中选择原始项目:
string[] partNumbers = { "US", "1", "UK", "Australia", "Germany", "70", "9" };
int value;
var result = partNumbers
.Select(s => new { isNumber = Int32.TryParse(s, out value), s, value })
.GroupBy(x => x.isNumber)
.OrderBy(g => g.Key)
.SelectMany(g => g.Key ? g.OrderBy(x => x.value) : g.OrderBy(x => x.s))
.Select(x => x.s)
.ToList();
返回:
"Australia",
"Germany",
"UK",
"US",
"1",
"9",
"70"
答案 4 :(得分:0)
string[] partNumbers = new string[]
{
"India", "US","UK", "Australia","Germany", "1", "7", "9"
};
var result = partNumbers.OrderBy(x =>
{
int i;
return int.TryParse(x, out i);
}).ThenBy(x=>x);