Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对包含字符串和/或数字的集合进行排序_C#_Linq_Sorting - Fatal编程技术网

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

C# 对包含字符串和/或数字的集合进行排序,c#,linq,sorting,C#,Linq,Sorting,我有一个100个元素的列表,看起来像这样: bool equal = collection .OrderBy(i => Array.IndexOf(order, i.Split('(').First())) .ThenBy(i => i.Split('(').Last().Replace(")", " ")) .SequenceEqual(collection2); 狗 猫(2) 伯德(34) 猫+狗(11) 狗(5) 此外,我还有一个特定的要求订单,比如: strin

我有一个100个元素的列表,看起来像这样:

bool equal = collection
  .OrderBy(i => Array.IndexOf(order, i.Split('(').First()))
  .ThenBy(i => i.Split('(').Last().Replace(")", " "))
  .SequenceEqual(collection2);
  • 猫(2)
  • 伯德(34)
  • 猫+狗(11)
  • 狗(5)
  • 此外,我还有一个特定的要求订单,比如:

    string[] order = {"dog", "bird", "cat", "cat + dog"};
    
    我需要我的方法按上述顺序排序,然后按数字排序,得到结果:

  • 狗(5)
  • 伯德(34)
  • 猫(2)
  • 猫+狗(11)
  • 目前我有这样的想法:

    bool equal = collection
      .OrderBy(i => Array.IndexOf(order, i.Split('(').First()))
      .ThenBy(i => i.Split('(').Last().Replace(")", " "))
      .SequenceEqual(collection2);
    
    但它不起作用<代码>然后按与第一次排序重叠。 另外,在输入
    int.Parse
    括号后,我得到一个异常


    请帮助我实现这一点。

    我建议将初始行拆分为匿名类实例:完成(并调试)后,您可以

    .OrderBy(item => Array.IndexOf(order, item.name))
    .ThenBy(item => item.count)
    
    实施:

      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));
    
    编辑:您的代码被修改
    Trim()
    添加到
    OrderBy
    中<代码>然后按
    重新设计

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

    没有检查完成。。。数据是完美的,或者一切都很顺利:

    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

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

    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();
    
    var集合=新列表{
    “狗”,
    "第二类",,
    "雀鸟(34)",,
    “猫+狗(11)”,
    "狗只(五)",,
    };
    字符串[]顺序={“狗”、“鸟”、“猫”、“猫+狗”};
    var regex=new regex(“^(?.*?\\s*(\\((?[0-9]+)\\))?$”;
    var结果=集合
    .选择(i=>
    {
    var match=regex.match(i);
    还新{
    content=i,
    名称=匹配。组[“名称”]。值,
    number=int.TryParse(match.Groups[“number”].值,out int number)
    ?数量
    : 1 };
    })
    .OrderBy(item=>Array.IndexOf(order,item.name))
    .ThenBy(项目=>项目编号)
    .选择(i=>i.content)
    .ToList();
    Console.WriteLine(string.Join(Environment.NewLine,result));
    Console.ReadLine();
    
    您是否计划创建自定义比较函数?可能重复的“100个元素列表”元素是字符串“cat(2)”的字面意思,还是具有属性
    cat
    2
    的元素将i.Split(“(”).Last()。替换(“)”,“)为数字帮助?i、 e.bool equal=collection.OrderBy(i=>Array.IndexOf(order,i.Split(“(”).First()).ThenBy(i=>int.Parse(i.Split(“(”).Last().Replace(“)).SequenceEqual(collection2);@Lucifer他还有一个步骤:按另一个数组排序你可以将
    \s*
    添加到模式
    var regex=new regex(“(?*)\”((?*)\)\((?[0-9])\)\)\);
    并摆脱
    Trim()
    .OrderBy(item=>Array.IndexOf(order,item.name))
    因为
    默认值(int)==0
    我怀疑它是否应该被使用;可能它应该是
    1
    …?数字:1
    -如果省略了数量-
    (数字)
    ,则提到一只动物:
    “狗”
    -一只狗,
    “狗(5)”
    -五只狗。@DmitryBychenko你说得对,这会让代码更好;-)我还为名称添加了一个非贪婪表达式,否则它会保留空格。