首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对包含字符串和/或数字的集合进行排序

对包含字符串和/或数字的集合进行排序
EN

Stack Overflow用户
提问于 2018-06-14 09:16:44
回答 3查看 80关注 0票数 1

我有一个100元素列表,这些元素如下所示:

  1. “禁止酷刑公约”(2)
  2. 鸟(34)
  3. 猫+狗(11)
  4. 狗(5)

此外,我还有一个特定的所需的订单,让我们说:

代码语言:javascript
复制
string[] order = {"dog", "bird", "cat", "cat + dog"};

我需要我的方法按上述顺序排序,然后按数字排序,结果是:

  1. 狗(5)
  2. 鸟(34)
  3. “禁止酷刑公约”(2)
  4. 猫+狗(11)

目前我有这样的事情:

代码语言:javascript
复制
bool equal = collection
  .OrderBy(i => Array.IndexOf(order, i.Split('(').First()))
  .ThenBy(i => i.Split('(').Last().Replace(")", " "))
  .SequenceEqual(collection2);

但不起作用。ThenBy重叠于第一次排序。同样,在将int.Parse输入ThenBy括号时,我将得到一个异常。

帮我实现这一目标。

EN

回答 3

Stack Overflow用户

发布于 2018-06-14 09:31:07

我建议将初始行拆分为匿名类实例:完成(并调试)此操作后,只需将

代码语言:javascript
复制
.OrderBy(item => Array.IndexOf(order, item.name))
.ThenBy(item => item.count)

执行情况:

代码语言:javascript
复制
  List<string> collection = new List<string> {
    "dog",
    "cat (2)",
    "bird (34)",
    "cat + dog (11)",
    "dog (5)",
  };

  string[] order = { "dog", "bird", "cat", "cat + dog" };

  var result = collection
    .Select(item => item.Split('('))
    .Select(parts => parts.Length == 1 // do we have "(x)" part?
       ? new { name = parts[0].Trim(), count = 1 } // no
       : new { name = parts[0].Trim(), count = int.Parse(parts[1].Trim(')')) }) // yes
    .OrderBy(item => Array.IndexOf(order, item.name)) // now it's easy to work with data
    .ThenBy(item => item.count)
    .Select(item => item.count == 1 // back to the required format
       ? $"{item.name}"
       : $"{item.name} ({item.count})")
    .ToList();

 Console.WriteLine( string.Join(Environment.NewLine, result));

结果:

代码语言:javascript
复制
dog
dog (5)
bird (34)
cat (2)
cat + dog (11)

编辑:您的代码修改了在OrderBy中添加的Trim()ThenBy重新设计

代码语言:javascript
复制
  var result = collection
    .OrderBy(i => Array.IndexOf(order, i.Split('(').First().Trim())) // Trim
    .ThenBy(i => i.Contains('(')                                     // two cases:
       ? int.Parse(i.Split('(').Last().Replace(")", ""))             // with "(x)" part
       : 1)                                                          // without
    .ToList();
票数 1
EN

Stack Overflow用户

发布于 2018-06-14 09:55:01

与使用regex的@Dmitry Bychenko完全相同的答案:

代码语言:javascript
复制
var collection = new List<string> {
    "dog",
    "cat (2)",
    "bird (34)",
    "cat + dog (11)",
    "dog (5)",
};

string[] order = { "dog", "bird", "cat", "cat + dog" };

var regex = new Regex("^(?<name>.*?)\\s*(\\((?<number>[0-9]+)\\))?$");

var result = collection
  .Select(i =>
    {
      var match = regex.Match(i);
      return new {
          content = i,
          name = match.Groups["name"].Value,
          number = int.TryParse(match.Groups["number"].Value, out int number) 
            ? number 
            : 1 };
    })
  .OrderBy(item => Array.IndexOf(order, item.name))
  .ThenBy(item => item.number)
  .Select(i => i.content)
  .ToList();

Console.WriteLine(string.Join(Environment.NewLine, result));
Console.ReadLine();
票数 1
EN

Stack Overflow用户

发布于 2018-06-14 09:32:51

没有检查..。数据是完美的,否则一切都会繁荣起来:

代码语言:javascript
复制
var res = (from x in collection
           let ix = x.LastIndexOf(" (")
           orderby Array.IndexOf(order, ix != -1 ? x.Remove(ix) : x),
               ix != -1 ? int.Parse(x.Substring(ix + 2, x.Length - 1 - (ix + 2))) : 0
           select x).ToArray();

注意ix != -1的双重处理。在orderby的第二行(即函数式LINQ中的ThenBy() )中,如果是ix == -1,则值为: 0)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50853882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档