c# - 使用 Linq 从树中获取具有特定属性的所有对象

标签 c# linq

我有一个类结构,如下所示:

class TestResults {
   public bool IsSuccess;
   public bool IsFailure;

   public IList<TestResults> SubTestResults;
}

因此,一个测试有多个子测试,上面捕获了结果。

我想找到所有 IsFailure = true 的 TestResults。

开头为:

var failures = from result in results
               where result.IsFailure
               select result;

这给了我 IsFailure=true 的顶级结果,但我想获得 IsFailure=true 的所有测试和子测试,并且所有这些都在列表中。是否有一个 linq 查询可以做到这一点,或者我应该使用老式循环?

更新: 我应该说我对这些类的使用意味着树只有 2 层深度(类的结构不在我的控制之下)。

所以我有:

Test1 - SubTest11
        SubTest12
        SubTest13

Test2 - SubTest21
        SubTest22

Test3 - SubTest31
        SubTest32
        SubTest33
        SubTest34

我需要所有 IsFailure = true 的子测试。

最佳答案

如果只有两个级别(即子测试不能有子测试),那么你可以这样做:

var failures = results.Union(results.SelectMany(r => r.SubTestResults))
                      .Where(r => r.IsFailure);

这获取结果列表并将其与所有结果子项的列表合并。

如果您可以有任意深度的子测试,那么您将需要更复杂的东西,因此我们首先为递归定义一个辅助函数。

IEnumerable<TestResults> AllResults(IEnumerable<TestResults> results)
{
    foreach(var tr in results)
    {
        yield return tr;
        foreach(var sr in AllResults(tr.SubTests))
            yield return sr;
    }
}

现在我们使用它并进行过滤

var failures = from result in AllResults(results)
               where result.IsFailure
               select results;

这应该可以解决问题。然而,我上面的 AllResults 实现并不是特别高效(请参阅 Wes Dyers blog for details ),因此您确实希望在 AllResults 上执行典型的递归到迭代转换。

IEnumerable<TestResults> AllResults(IEnumerable<TestResults> results)
{
    var queued = new Queue<TestResult>(results); 
    while(queued.Count > 0)
    {
        var tr = queued.Dequeue();
        yield return tr;
        foreach(var sr in tr.SubTests)
            queued.Enqueue(sr);
    }
}

请注意,您仍然应该添加各种空检查以确保完整性

关于c# - 使用 Linq 从树中获取具有特定属性的所有对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3196751/

相关文章:

c# - 通过 ASP.net 页面进行 FTP 传输

c# - 为什么我每天使用带有 ASMX Web 服务的 log4net 获得两个日志文件?

c# - Linq 中的双重或三重 "where"子句

c# - 如何将 Azure 移动服务与 Cordova 项目 AngularJS 和 C# 一起使用?

c# - 尽管有 WS_EX_COMPOSITED 标志和 DoubleBuffered 属性,但在调整大小后闪烁

c# - Expression.Body.Expressions——如何使用它?

c# - 使用 Linq 获取列表 <> 的项目数

c# - XML LINQ 查询不返回任何数据

c# - 如何让 NHibernate SchemaExport 创建 SQL Server 时间戳列?

c# - 如何将两个 LINQ 表达式中的 .Select 合并为一个?