我想根据特定属性检查2个列表中的任何元素是否相同,然后返回true,false。
现在我有:
public bool CanEdit(List<RoleType> roles)
{
var rolesThatCanEdit = new List<RoleType>{
RoleType.Administrator,
RoleType.Editor
};
//check if the roles can edit.
return rolesThatCanEdit.Intersect(roles).Any();
}
但是我猜这是如何工作的,它会创建一个新列表,然后检查列表中是否有任何内容。有没有办法可以在第一个匹配的元素上返回true?最糟糕的情况是没有匹配的元素,它将在内部遍历整个列表。
答案 0 :(得分:10)
Linq的Intersect()
方法将在内部为一个列表创建并使用HashTable
,然后迭代另一个列表以查看是否存在任何交集,然后生成那些相交的元素 - 所以在Big中O项如果完整列表被迭代,你有O(m)+ O(n) - 但由于Any()
运算符,迭代将在第一个产生的元素之后停止 - 仍然在最坏的情况下(没有交集)仍需要对H(1)中的Hashtable进行m次查找,因此你有O(n)+ O(m)。
这非常有效(并且至少在Big O方面你不能做得更好)并且肯定会做得更好,你会牺牲很多可读性 - 直到你通过测量这个性能对你来说是个问题证明我会去与Linq。
答案 1 :(得分:6)
它不仅不会计算完整的交集,它会将第二个输入列表(扩展方法上不是this
参数的列表)转换为哈希表,以实现非常快速的重复查找。 (rolesThanCanEdit.Intersect(roles)
与roles.Intersect(rolesThatCanEdit)
)
答案 2 :(得分:0)
它已经是最优的:最后一个链式扩展将提前输出,所有枚举器将被处理而不会运行完成
答案 3 :(得分:0)
使用集合(HashSet<>
)代替列表和Linq。
将所有元素放入集合中,然后迭代其他列表并进行比较。
这是O(n+m)
。