是否可以简化以下Linq表达式? [英] Is it possible to simplify the following Linq expression?
问题描述
我必须维护一个代码,以比较两个集合的项目
I have to maintain a code that makes a comparison between the items of two collections
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2)) &&
!list2.Any(item2 => Cond2(item1,item2))
)
我试图简化所有这些迭代,我想知道上面的代码是否等同于下面的代码
I was trying to simplify all those iterations and I wondered whether the above code is equivalent to the following
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2) && !Cond2(item1,item2)))
这似乎更易于管理,所以我尝试了一些测试用例,初步结果还可以.您是否认为总体上是正确的,还是可以发现需要第一个较长的代码(与第二个较短的代码不同)的情况?
That seems more manageable, so I tried with some test cases and the initial results were ok. Do you think that it is true in general or can you spot a situation where the first, longer code is needed (=different from the second, shorter one)?
评论中的一些有趣注释.
Some interesting notes from the comments.
- the above seems to be equivalent if and only if
Cond1
determines a unique key condition forlist2
, but of course this is not true in the general case. - inverting the order of the two
Any
statement appears to be more efficient as pointed out by Knoop.
关于第2点,请考虑使用更现实的业务代码
Regarding point 2, please consider that a more realistic business code would be
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2)) &&
!list2.Any(item2 => Cond1(item1,item2) && Cond2(item1,item2))
)
因为这里描述的典型业务问题是比较两个集合并寻找缺失,匹配和不同的记录,而后者(不同但不是缺失的记录)就是问题中报告的内容
because the typical business problem described here is comparing 2 collections and looking for missing, matching and different records, the latter (different - but not missing - records) being what is reported in the question
推荐答案
这里描述的典型业务问题是比较两个集合,并寻找缺失,匹配和不同的记录,后者(不同但不是缺失的记录)是问题中所报告的内容
the typical business problem described here is comparing 2 collections and looking for missing, matching and different records, the latter (different - but not missing - records) being what is reported in the question
如果您既想要功能又高效的解决方案,则可以使用Enumerable.Aggregate
LINQ扩展方法,如类似的 answer中所建议,在第一个集合list1
上包裹在外部Where
中.
If you want both a functional and an efficient solution you can use the Enumerable.Aggregate
LINQ extension method, as suggested in a similar answer, wrapped inside the external Where
over the first collection list1
.
(bool allVerified, bool anyVerified) =
list2.Aggregate(
ValueTuple.Create(true, false),
(tuple, item) => ValueTuple.Create(
tuple.Item1 && !(Cond1(item1,item) && Cond2(item1,item)),
tuple.Item2 || Cond1(item1, item)) );
return allVerified && anyVerified;
完整摘要小提琴在这里.
这篇关于是否可以简化以下Linq表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!