【问题标题】:string sorting in C#C#中的字符串排序
【发布时间】:2014-02-25 05:21:13
【问题描述】:

我有一个字符串数组,如下所示:

"access"
"Addition"
"account"
"base"
"Brick"
"zammer"
"Zilon"

我希望他们按照以下规则对它们进行排序"

  1. 给定字符的大写字母应该放在第一位。
  2. 大写和小写字母应按各自的组排序。

因此,输出应该是:

"Addition"
"access"
"account"
"Brick"
"base"
"Zilon"
"zammer"

我使用的语言是 C# 和 .Net 4.0。

【问题讨论】:

    标签: c# string linq sorting


    【解决方案1】:

    正确的OrderBy/ThenBy 调用集就可以解决问题。

    1. 按首字母小写排序,首先得到所有as和As,然后是bs和Bs等。
    2. 然后是IsLower(firstCharacter),它将首先获取每个字母的大写项目。
    3. 然后是整个字符串。
    var sorted = source.OrderBy(s => char.ToLower(s[0]))
                       .ThenBy(s => char.IsLower(s[0]))
                       .ThenBy(s => s)
                       .ToList();
    

    【讨论】:

    • 最好是:source.OrderBy(s => char.ToLower(s[0])).ThenByDescending(s => s)。这似乎可以完成这项工作。无论如何 +1。
    • +1,但这不是只有在字符串中间没有大写字母的情况下才有效吗? (当然,OP 的示例中没有任何内容,但所述要求并不排除这种可能性)。
    • @Baldrick 是的,我假设上限/下限规则仅适用于第一个字符。
    • @MarcinJuraszek:嗯.. 得到一个更通用的解决方案会很好.. 但可能正好适合 OP 的问题!干得好。
    • 字符串之间可以很好地包含大写字母。
    【解决方案2】:

    这样试试

    List<string> list = new List<string>();
    list.Add("access");
    list.Add("Addition");
    list.Add("account");
    list.Add("base")
    list.Add("Brick")
    list.Add("zammer")
    list.Add("Zilon")
    list = list.Where(r => char.IsLower(r[0])).OrderBy(r => r)
          .Concat(list.Where(r => char.IsUpper(r[0])).OrderBy(r => r)).ToList();
    for (int i = 0; i < list.Count; i++)
        Console.WriteLine(list[i]);
    

    【讨论】:

      【解决方案3】:

      以下解决方案适用于多个 Caps。

         static void Main(string[] args)
          {
      
              var names = new List<String>() {
              "access",
              "Addition",
              "ADDition",
              "ADdition",
              "account",
               "base",
              "Brick",
              "zammer",
              "Zilon"
              };
      
      
              names.Sort((one, two) =>
              {
                  int result = 0;
      
                  var oneArray = one.ToCharArray();
                  var twoArray = two.ToCharArray();
      
                  var minLength = Math.Min(oneArray.Length, twoArray.Length) - 1;
                  var i = 0;
      
                  while (i < minLength)
                  {
                      //Diff Letter
                      if (Char.ToUpper(one[i]) != Char.ToUpper(two[i]))
                      {
                          result = Char.ToUpper(one[i]) - Char.ToUpper(two[i]);
                          break;
                      }
      
                      // Same Letter, same case
                      if (oneArray[i] == twoArray[i])
                      {
                          i++;
                          continue;
                      }
                      // Same Letter, diff case
                      result =  one[i] - two[i];
                      break;
                  }
      
                  return result;
              });
      
              foreach (string s in names)
                  Console.WriteLine(s);
      
              Console.WriteLine("done");
      

      【讨论】:

        【解决方案4】:

        如果你想超越第一个字符,我应该实现一个比较器:

        class MyComparer : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                if ((x == null) && (y == null))
                {
                    return 0;
                }
        
                if (x == null)
                {
                    return 1;
                }
        
                if (y == null)
                {
                    return -1;
                }
        
                var l = Math.Min(x.Length, y.Length);
                for (var i = 0; i < l; i++)
                {
                    var c = x[i];
                    var d = y[i];
                    if (c != d)
                    {
                        if (char.ToLowerInvariant(c) == char.ToLowerInvariant(d))
                        {
                            return StringComparer.Ordinal.Compare(new string(c, 1), new string(d, 1));
                        }
                        else
                        {
                            return StringComparer.OrdinalIgnoreCase.Compare(new string(c, 1), new string(d, 1));
                        }
                    }
                }
        
                return x.Length == y.Length ? 0 : x.Length > y.Length ? 1 : -1;
            }
        }
        

        然后使用它:

        var myComparer = new MyComparer();
        source.OrderBy(s => s, myComparer);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-03-04
          • 2016-01-29
          • 2012-03-10
          • 2014-06-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多