LINQ的If .Any匹配.Any

6
我有两个字符串数组,我想返回它们中任何一个是否存在于“_authRole”数组中。怎么做呢?
 string[] _userRoles = userdata.Split(',');

 string[] _authRoles = AuthRoles.Split(',');


 bool isAuthorized = _authRoles.Any(_userRoles ??);

/M

3个回答

12
如果您想确定 _authRoles_userRoles 是否至少有一个共同的项,那么请使用以下代码:

如果你想要确认_authRoles_userRoles是否拥有至少一个共同项目,则使用:

bool isAuthorized = _authRoles.Intersect(_userRoles).Any();

您也可以以任何您选择的方式查询Intersect的结果。


+1. 我以前并没有使用过 Any 这种方式,这比我提出的解决方案更好。 - Adam Robinson
谢谢。这是那种事情,第一次想到后就立刻显而易见了。 :-) - Jon

10

试一下这个:

Boolean isAuthorized =
    _userRoles.Any(user => _authRoles.Contains(user));

4
假设列表的大小为N和M,可能的情况是没有匹配。安德鲁的解决方案时间复杂度为O(NM),额外内存占用为O(1)。亚当的解决方案时间和内存复杂度均为O(N+M),但可以像乔恩的解决方案一样更清晰地编写。
另一种基本与亚当和乔恩相同的解决方案是将两个列表连接起来。
var joined = from user in userRoles 
             join auth in authRoles 
             on user equals auth 
             select user;
return joined.Any();

这个文本有点比必要的重,但读起来很流畅。 :-)


它们肯定是O(NM)和O(N+M)吗?还是LINQ会进行优化,就像Jon的解决方案末尾的Any()一样,它只需要在找到一个结果之前就可以返回。 - cjk
2
@Jon:取第一个列表。用该列表构建哈希表HT。建立HT的成本为O(N)时间复杂度。对于第二个列表中的每个项目,请询问HT是否在第一个列表中。这是O(M)测试,如果HT编写良好,则每个测试成本为O(1)时间复杂度。总计:时间复杂度为O(N) + O(M)。但是你提到的排序想法很好;如果由于某种原因我们没有O(1)的哈希表,我们至少可以以O(N log N)的成本构建可二分搜索的数组。每次搜索的成本为O(log N),因此总成本将为O(N log N) + O(M log N)。 - Eric Lippert
2
@Jon:我认为你会发现LINQ-to-objects一直在代表你构建哈希表。如果你不喜欢它的行为,那么请随意编写自己的LINQ-to-objects实现;没有任何阻止你的东西。而且实现通常不知道问题的规模;如果输入不是IList,则计算大小本身就是O(n)。 - Eric Lippert
关于操作系统:对于M个项目中的每一个,构建一个具有20K节点的适当二叉树。对于N个项目中的每一个,计算它们的哈希值。随着M和N的增长,时间将会是1000 * M + N。这比1000 * (M+N)少,仍然是O(M+N)。这就是我开始思考的方式,但显然我停得太早了。谢谢! - Jon
最后还有一点:这次交流也让我认识到,即使在这不是显然的情况下,一个非幼稚的“GetHashCode”实现也可能非常重要。再次感谢。 - Jon
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接