【问题标题】:Linq to Objects ordering by arbitrary number of parametersLinq to Objects 按任意数量的参数排序
【发布时间】:2011-11-11 11:40:21
【问题描述】:

我有一个定义排序的Func 列表:

var ordering = new List<Func<Person, IComparable>> 
                 { x => x.Surname, x => x.FirstName };

我可以对结果进行排序,例如...

people = people.OrderBy(ordering[0]).ThenBy(ordering[1]);

当列表可以包含任意数量的顺序排序时,我试图弄清楚如何执行上述操作。有可能吗?

【问题讨论】:

    标签: c# linq dynamic sql-order-by func


    【解决方案1】:

    您可能希望通过动态构建您的表达来做到这一点。更多信息在这里:Dynamic LINQ and Dynamic Lambda expressions?

    【讨论】:

      【解决方案2】:
      people = people.OrderBy(ordering[0]).ThenBy(ordering[1]).ThenBy(ordering[2]);
      

      相同
      var orderedPeople = people.OrderBy(ordering[0]);
      orderedPeople = orderedPeople.ThenBy(ordering[1]);
      orderedPeople = orderedPeople.ThenBy(ordering[2]);
      people = orderedPeople;
      

      所以你只需像这样编写一个循环:

      if (ordering.Count != 0)
      {
          var orderedPeople = people.OrderBy(ordering[0]);
          for (int i = 1; i < ordering.Count; i++)
          {
              orderedPeople = orderedPeople.ThenBy(ordering[i]);
          }
          people = orderedPeople;
      }
      

      【讨论】:

      • 你实际上不需要检查计数,如果你只是切换循环中正在做的事情
      • 出于某种原因,我没有意识到“与此相同”位是正确的。我认为他们必须直接跟随。非常感谢。
      • hmmmm...实际上它们并不相同。 ThenByOrderedEnumerable&lt;T&gt; 上运行,这就是我记忆中的方式。我想我可以解决这个问题。
      【解决方案3】:

      你应该可以做类似的事情

      people = people.OrderBy(ordering[0])
      foreach(var order in ordering.Skip(1))
      {
        people = people.ThenBy(order);
      }
      

      交替

       for(i = 0; i < ordering.Count; i++)
       {
          people = i == 0 ? people.OrderBy(ordering[i]) : people.ThenBy(ordering[i]);
       }
      

      【讨论】:

        【解决方案4】:

        请记住,LINQ 执行是延迟的。您可以在访问结果之前按顺序构建表达式,执行以下操作:

        var ordered = unordered.OrderBy(ordering.First());
        foreach (var orderingItem in ordering.Skip(1))
        {
            ordered = ordered.ThenBy(orderingItem);
        }
        

        【讨论】:

          【解决方案5】:

          正如其他人所提到的,您可以使用循环来执行此操作。

          如果您愿意,也可以使用Aggregate 运算符:

          // Requires a non-empty ordering sequence.
          var result2 = ordering.Skip(1)
                                .Aggregate(people.OrderBy(ordering.First()), Enumerable.ThenBy); 
          

          (或)

          // Shorter and more "symmetric" but potentially more inefficient.
          // x => true should work because OrderBy is a stable sort.
          var result = ordering.Aggregate(people.OrderBy(x => true), Enumerable.ThenBy);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-03-03
            • 1970-01-01
            • 2011-10-22
            • 1970-01-01
            • 1970-01-01
            • 2021-03-17
            • 1970-01-01
            相关资源
            最近更新 更多