【问题标题】:To Order By Descending sub-elements using LINQ or Lambda Expression使用 LINQ 或 Lambda 表达式按降序排列子元素
【发布时间】:2019-04-28 09:22:13
【问题描述】:

我在对 List 中的子元素进行排序时遇到问题,并找到了讨论 List<T> vs IEnumerable<T> in foreach 的主题。我想知道如何使用 LINQ 或 Lambda 表达式对子 List 进行排序。有人可以推荐我吗?代码示例如下:

public class Parent
{
    // Other properties...
    public IList<Child> Children { get; set; }
}

public IEnumerable<Parent> DoStuff()
{
    var result = DoOtherStuff() // Returns IEnumerable<Parent>
        .OrderByDescending(SomePredicate) 
        .ThenBy(AnotherPredicate); // This sorting works as expected in the return value.

    foreach (Parent parent in result)
    {
        parent.Children = parent.Children.OrderBy(YetAnotherPredicate).ToList();
        // When I look at parent.Children here in the debugger, it's sorted properly.
    }

    return result;
    // When I look at the return value, the Children are not sorted.
}

【问题讨论】:

  • 您应该在订购 DoOtherStuffResult() 后使用 ToList(),或者使用示例中 foreach 的 yield return。

标签: c# lambda foreach


【解决方案1】:

您每次枚举IEnumerable 的返回IEnumerable 时都枚举result,并在DoStuff 本身的循环内多加一次。但是,由于延迟执行,您在循环中所做的修改不会保留:下次您枚举DoStuff() 时,会再次调用DoOtherStuff 等。

您可以通过多种方式解决此问题:

  • 在排序子级之前将result转换为列表,即

    DoOtherStuff() // Returns IEnumerable<Parent>
    .OrderByDescending(SomePredicate) 
    .ThenBy(AnotherPredicate)
    .ToList();
    
  • Select 中添加子排序:

    DoOtherStuff() // Returns IEnumerable<Parent>
    .Select(parent => {
        parent.Children = parent.Children.OrderBy(YetAnotherPredicate).ToList();
        return parent;
    })
    .OrderByDescending(SomePredicate) 
    .ThenBy(AnotherPredicate)
    .ToList();
    
  • 在循环中使用yield return result(这是Select 解决方案的变体)。

【讨论】:

    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 2013-03-08
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多