C# 首先按字母值对列表排序,然后按数字值对列表排序

C# 首先按字母值对列表排序,然后按数字值对列表排序,c#,linq,C#,Linq,我尝试了上述代码,并期望得到以下输出: 澳大利亚 德国 印度 英国 我们 1. 7. 9 编辑: 数字应按数字顺序排列(1、7、9、70等),而非数字应始终按词汇顺序排列,即使里面有数字(“A3stralia”、“澳大利亚”、“德国”)。尝试以下方法: class ListSort { static void Main(string[] args) { string[] partNumbers = new string[] {

我尝试了上述代码,并期望得到以下输出:

澳大利亚
德国
印度
英国
我们
1.
7.
9
编辑: 数字应按数字顺序排列(1、7、9、70等),而非数字应始终按词汇顺序排列,即使里面有数字(“A3stralia”、“澳大利亚”、“德国”)。

尝试以下方法:

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();                    
    }
}
请注意,这仅在数据为数字或文本时有效,而在有“U2S”这样的值时无效。不过,如果你需要的话,我也可以将其更改为适用于这些情况。而且,数字字符串仍然是按字符串排序的,因此“10”在“2”之前

A3stralia
70
添加到列表中时,您希望结果如何

编辑:已为新约束更改:

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();
试试这个:

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();                    
    }
}
请注意,这仅在数据为数字或文本时有效,而在有“U2S”这样的值时无效。不过,如果你需要的话,我也可以将其更改为适用于这些情况。而且,数字字符串仍然是按字符串排序的,因此“10”在“2”之前

A3stralia
70
添加到列表中时,您希望结果如何

编辑:已为新约束更改:

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

以下解决方案将字符串序列投影到匿名类型
{isNumber,s,value}
,其中包含序列中的当前项、项是否为整数的信息以及可能的解析结果。然后,如果将新序列分为两组,一组用于数字,另一组用于其他字符串。每组按数字比较、字符串字母顺序排序。并从展开的组中选择原始项:

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();
返回:

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

以下解决方案将字符串序列投影到匿名类型
{isNumber,s,value}
,其中包含序列中的当前项、项是否为整数的信息以及可能的解析结果。然后,如果将新序列分为两组,一组用于数字,另一组用于其他字符串。每组按数字比较、字符串字母顺序排序。并从展开的组中选择原始项:

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();
返回:

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

如果数字部分按字典顺序排列并不重要:

    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);    
这只是检查是否所有字符都是数字。如果要首先使用数字,请使用
可枚举.OrderByDescending

正如对其中一个答案的评论所述,如果您想对数字进行数字排序,则需要首先解析它们:

var result = partNumbers.OrderBy(s => s.All(Char.IsDigit)).ThenBy(s => s).ToList();   
我使用此扩展在LINQ查询中将
字符串
解析为
可空

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

如果数字部分按字典顺序排列并不重要:

    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);    
这只是检查是否所有字符都是数字。如果要首先使用数字,请使用
可枚举.OrderByDescending

正如对其中一个答案的评论所述,如果您想对数字进行数字排序,则需要首先解析它们:

var result = partNumbers.OrderBy(s => s.All(Char.IsDigit)).ThenBy(s => s).ToList();   
我使用此扩展在LINQ查询中将
字符串
解析为
可空

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

到目前为止,似乎所有的反应都大致相同,但都太复杂了。我的尝试:

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;
    }
}
或者,使用提取的辅助对象方法:

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);

到目前为止,似乎所有的反应都大致相同,但都太复杂了。我的尝试:

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;
    }
}
或者,使用提取的辅助对象方法:

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);

字符串“50美分”怎么样?它应该被视为字符串还是数字?另外,如果您将使用
70
而不是
7
,该怎么办?它应该是最后一个吗?字符串
“50美分”怎么样?它应该被视为字符串还是数字?另外,如果您将使用
70
而不是
7
,该怎么办?这应该是最后一个吗?哇,我疲惫的眼睛把帖子和答案混在一起了:-/@RaphaëlAlthaus:我没有看到,因此编辑了我的答案。哇,我疲惫的眼睛把帖子和答案混在一起了:-/@RaphaëlAlthaus:我没有看到,因此编辑了我的答案。@user2864740:那么?我在回答中这样说。我们需要OP确认他没有指定的病例的正确分类。如果是A3stralia和70……A3stralia应该高于/低于澳大利亚(无所谓),70应该靠近9,即1,7,9,70@user3080252:请不要在对某些答案的评论中添加如此重要的信息。改为(同时)编辑您的问题。@user3080252:我已经更新了答案,以给出您想要的结果-文本按文本排序,数字按数字排序。@user2864740:那么?我在回答中这样说。我们需要OP确认他没有指定的病例的正确分类。如果是A3stralia和70……A3stralia应该高于/低于澳大利亚(无所谓),70应该靠近9,即1,7,9,70@user3080252:请不要在对某些答案的评论中添加如此重要的信息。改为(同时)编辑您的问题。@user3080252:我已经更新了答案以给出您想要的结果-文本按文本排序,数字按数字排序。