[英]Check if any item in a list matches any item in another list
A coleague asked me to write a one-liner to replace the following method: 一个coleague让我写一个单行代替以下方法:
public static bool IsResourceAvailableToUser(IEnumerable<string> resourceRoles, IEnumerable<string> userRoles)
{
foreach (var userRole in userRoles)
foreach (var resourceRole in resourceRoles)
if (resourceRole == userRole)
return true;
return false;
}
Resharper and I came up with this: Resharper和我想出了这个:
public static bool IsResourceAvailableToUser(IEnumerable<string> resourceRoles, IEnumerable<string> userRoles)
{
return userRoles.Where(resourceRoles.Contains).Count() > 0;
}
Is there a better way? 有没有更好的办法?
Given LINQ, yes: 鉴于LINQ,是的:
return userRoles.Intersect(resourceRoles).Any();
Note that aside from the use of Intersect
to turn it into O(m) + O(n) instead O(m * n), using Any
is more efficient than using Count() > 0
- you know the answer as soon as you've found the first match. 请注意,除了使用
Intersect
将其转换为O(m)+ O(n)而不是O(m * n)之外,使用Any
比使用Count() > 0
更有效 - 您只要知道答案找到了第一场比赛。
You could write a generic extension method that would handle many cases. 您可以编写一个可以处理许多情况的通用扩展方法。 The meat of the function itself is one line.
功能本身就是一条线。
/// <summary>
/// Compares both lists to see if any item in the enumerable
/// equals any item in the other enumerable.
/// </summary>
public static bool AnyItem<T>(this IEnumerable<T> source, IEnumerable<T> other, IEqualityComparer<T> comparer = null)
{
return (comparer == null ? source.Intersect(other) : source.Intersect(other, comparer)).Any();
}
public static bool AnyItem<T>(this IEnumerable<T> source, IEnumerable<T> other)
{
return source.Any(s => other.Any(o => EqualityComparer<T>.Default.Equals(s, o)));
}
I
think this is also more efficient than the current answer
(It's not).
我
认为这也比当前的答案更有效
(
事实
并非如此)。 I would have to check if getting the EqualityComparer is expensive, but I'm willing to doubt it. 我必须检查EqualityComparer是否昂贵,但我愿意怀疑它。
You could also extend this function to accept an Expression that would evaluate what properties to compare for enumerables that contain objects. 您还可以扩展此函数以接受一个Expression,该Expression将评估要包含对象的枚举的要比较的属性。
public static bool AnyItem<T, TResult>(
this IEnumerable<T> source,
IEnumerable<T> other,
Expression<Func<T, TResult>> compareProperty = null)
{
if (compareProperty == null)
{
return source.Any(s => other.Any(o => EqualityComparer<T>.Default.Equals(s, o)));
}
return source.Any(s => other.Any(o =>
EqualityComparer<TResult>.Default.Equals(
s.GetPropertyValue(compareProperty),
o.GetPropertyValue(compareProperty))));
}
public static TValue GetPropertyValue<TTarget, TValue>(
this TTarget target, Expression<Func<TTarget, TValue>> memberLamda)
{
var memberSelectorExpression = memberLamda.Body as MemberExpression;
var property = memberSelectorExpression?.Member as PropertyInfo;
return (TValue)property?.GetValue(target);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.