我怎样才能避免这个集合迭代两次呢?
本文关键字:两次 迭代 集合 能避免 | 更新日期: 2023-09-27 18:08:26
注意:由于保密原因,我已经更改了集合的名称。
考虑以下代码:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag))) ||
o2.Collection1
.Any(cpd => cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
显然,我所做的是将详细标志扁平化为一个整体标志,但这段代码将o2.Collection1
迭代两次。
我不明白SelectMany
是如何完成这项工作的,因为标志在两个不同的集合上(即我没有将集合的集合扁平化)。
我怎样才能不那样做呢?
注:我感觉就像Jon Skeet,当我读到这篇文章时(使用LINQ来平化分层数据集-有一个警告)基本上说我被卡住了。但希望我读错了!
如果集合具有相同的类型(或具有定义足够信息的公共基类型),则可以在查询中简单地将它们连接起来:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1.Concat(cpd.Collection2)
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
请注意,这里的主要优点只是使查询更简单,并减少了代码重复。只要你的集合实际上是一个内存集合,它就不会对它的性能有任何明显的影响
如果它们的类型不兼容(或者与给出的示例不同,每个子集合的谓词存在细微差异),那么您可以管理的最佳方法是将两个子查询都拉到主集合的谓词中:
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)) ||
cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));
您可以使用单个迭代直到第一层,然后分支到两个单独的查询。
o.Flag =
o2.Collection1
.Any(cpd => cpd.Collection1
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)) ||
cpd.Collection2
.Any(plc => plc.Collection1
.Any(vd => vd.DetailedFlag)));