【发布时间】:2020-04-30 15:37:16
【问题描述】:
我必须维护一个在两个集合的项目之间进行比较的代码
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2)) &&
!list2.Any(item2 => Cond2(item1,item2))
)
我试图简化所有这些迭代,我想知道上面的代码是否等同于下面的代码
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2) && !Cond2(item1,item2)))
这似乎更易于管理,所以我尝试了一些测试用例,初步结果还可以。您认为总体上是正确的还是您能发现需要第一个较长代码的情况(=不同于第二个较短的代码)?
编辑以反映 cmets
来自 cmets 的一些有趣的笔记。
- 当且仅当
Cond1确定list2的唯一键条件时,上述内容似乎是等价的,但在一般情况下当然不是这样。 - 颠倒两个
Any语句的顺序似乎比pointed out by Knoop 更有效。
关于第2点,请考虑更现实的业务代码
list1.Where(item1 => list2.Any(item2 => Cond1(item1,item2)) &&
!list2.Any(item2 => Cond1(item1,item2) && Cond2(item1,item2))
)
因为这里描述的典型业务问题是比较 2 个集合并查找缺失、匹配和不同的记录,后者(不同但不缺失的记录)是问题中报告的内容
【问题讨论】:
-
第二条语句和第一条语句不一样。他们会在不同的情况下给出不同的结果
-
第一个不编译。您不能两次声明
item2。请提供实际运行的代码 -
抱歉,错过了右括号。你完全正确
-
说阿杰甘地是正确的。他们可以给出不同的结果。假设在第二个
Anyitem2被称为item3,现在更容易看到item2和item3可以是不同的项目。所以基本上第一个说“list1中是否有任何项目在list2中有一个项目可以满足Cond1但list2中没有项目可以满足Cond2?”第二个会说“list1 中是否有任何项目,其中 list2 中有项目满足 Cond1 但不满足 Cond2”(因此它必须是 list2 中的相同项目) -
是的,但要使第一个为假,您需要迭代整个列表。在评估第一个元素之后,第二个可能已经是错误的。因此,如果期望男孩条件以相同的机会返回 true,这肯定是可证明的