【问题标题】:How to order lists without respecting certain characters?如何在不尊重某些字符的情况下排序列表?
【发布时间】:2019-08-06 14:10:27
【问题描述】:

我目前有一个字符串列表,需要在不考虑以下字符的情况下进行排序('.', ',', '-', '\''

示例

        var cities = new List<string>()
        {                
            "Aigle ",
            "Bulle",
            "La Chaux-de-Fonds",
            "L'Abbaye",
            "Malleray",            
            "Sierre",
            "S. City",
            "St-Aubin",
            "St-Cergue",
            "St-Gingolph",
            "St-Légier-La Chiesaz",
            "St-Maurice",
            "St-Sulpice",
            "St-Sulpice",
            "Staad"
        };

默认下单

var ordered = cities
  .OrderBy(x => x)
  .ToList();

输出

"Aigle"
"Bulle"
"La Chaux-de-Fonds"
"L'Abbaye"
"Malleray"
"S. City"
"Sierre"
"Staad"
"St-Aubin"
"St-Cergue"
"St-Gingolph"
"St-Légier-La Chiesaz"
"St-Maurice"
"St-Sulpice"
"St-Sulpice"

而我想要的输出必须是这样的。

"Aigle "
"Bulle"
"L'Abbaye"
"La Chaux-de-Fonds"
"Malleray"
"S. City"
"Sierre"
"St-Aubin"
"St-Cergue"
"St-Gingolph"
"St-Légier-La Chiesaz"
"St-Maurice"
"St-Sulpice"
"St-Sulpice"
"Staad"

我通过这样做得到了我想要的输出。

var ordered = cities
  .OrderBy(x => x.Replace(".", " ").Replace("-", " ").Replace("'", " "))
  .ToList();

老实说,我不知道我在做什么。

有没有其他方法可以得到想要的结果?

【问题讨论】:

  • 如果您想要可读性,请使用Regex。如果您想要性能,请编写一个自定义比较方法,该方法对字符串进行操作,就像对数组进行操作一样。
  • “如果你想要可读性,请使用正则表达式”呃……好吧……正则表达式有很多优点,但“可读性”并不是其中之一。

标签: c# linq sorting


【解决方案1】:

也许转型可以帮助你

var ordered = cities
                .Select(city => new { Name = city, NameForOrdering = string.Join(string.Empty, city.Where(c => Char.IsLetterOrDigit(c)).ToArray()) })

                .OrderBy(city => city.NameForOrdering)
                .Select(city => city.Name)
                .ToList();

这可以作为一种快速而肮脏的方式来帮助您克服障碍或测试事物,但真正的解决方案是使用 OrderBy 的第二个重载,这需要您的自定义相等 compare-r。

【讨论】:

    【解决方案2】:

    好吧,我们只能按 字母 排序(我们忽略,即删除所有非字母字符):

      var ordered = cities
        .OrderBy(city => string.Concat(city.Where(c => char.IsLetter(c))), 
                 StringComparer.CurrentCultureIgnoreCase)
        .ToList();
    
      // Let's have a look
      Console.Write(string.Join(Environment.NewLine, ordered));
    

    我们会得到以下订单

    Aigle 
    Bulle
    L'Abbaye
    La Chaux-de-Fonds
    Malleray
    S. City
    Sierre
    Staad
    St-Aubin
    St-Cergue
    St-Gingolph
    St-Légier-La Chiesaz
    St-Maurice
    St-Sulpice
    St-Sulpice
    

    如果您想将所有非字母视为空格 ' '(您当前的代码):

     var ordered = cities
        .OrderBy(city => string.Concat(city.Select(c => char.IsLetter(c) ? c : ' ')), 
                 StringComparer.CurrentCultureIgnoreCase)
        .ToList();
    

    订单将是

    Aigle 
    Bulle
    L'Abbaye
    La Chaux-de-Fonds
    Malleray
    S. City
    Sierre
    St-Aubin
    St-Cergue
    St-Gingolph
    St-Légier-La Chiesaz
    St-Maurice
    St-Sulpice
    St-Sulpice
    Staad
    

    Staad位置的订单差异

    【讨论】:

      【解决方案3】:

      通过替换需要忽略的字符来对列表进行排序同时忽略指定字符的一种方法。

      例如,对于字符串cities的列表

      var cities = new List<string>()
              {                
                  "Aigle ",
                  "Bulle",
                  "La Chaux-de-Fonds",
                  "L'Abbaye",
                  "Malleray",            
                  "Sierre",
                  "S. City",
                  "St-Aubin",
                  "St-Cergue",
                  "St-Gingolph",
                  "St-Légier-La Chiesaz",
                  "St-Maurice",
                  "St-Sulpice",
                  "St-Sulpice",
                  "Staad"
              };
      

      选项 1:不使用正则表达式

      var charList = new List<char>{'.', ',', '-', '\''};
      var result = cities.OrderBy(x => charList.Aggregate(x, (c1, c2) => c1.Replace(c2, ' '))).ToArray();
      

      选项 2:使用正则表达式。

      var charList = new List<char>{'.', ',', '-', '\''};
      var regex = new Regex($"[{string.Join("",charList.OrderBy(x=>x))}]*");
      var result = cities.OrderBy(x=> regex.Replace(x," "));
      

      输出

      Aigle  
      Bulle 
      L'Abbaye 
      La Chaux-de-Fonds 
      Malleray 
      S. City 
      Sierre 
      St-Aubin 
      St-Cergue 
      St-Gingolph 
      St-Légier-La Chiesaz 
      St-Maurice 
      St-Sulpice 
      St-Sulpice 
      Staad 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-27
        • 1970-01-01
        • 2012-04-05
        • 2015-01-28
        • 1970-01-01
        • 2023-01-10
        • 2021-11-08
        相关资源
        最近更新 更多