gre*_*ade 11 c# algorithm .net-3.5
一个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;
}
Run Code Online (Sandbox Code Playgroud)
Resharper和我想出了这个:
public static bool IsResourceAvailableToUser(IEnumerable<string> resourceRoles, IEnumerable<string> userRoles)
{
return userRoles.Where(resourceRoles.Contains).Count() > 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
Jon*_*eet 23
鉴于LINQ,是的:
return userRoles.Intersect(resourceRoles).Any();
Run Code Online (Sandbox Code Playgroud)
请注意,除了使用Intersect将其转换为O(m)+ O(n)而不是O(m*n)之外,使用Any比使用更有效Count() > 0- 一旦找到第一个匹配就知道答案了.
您可以编写一个可以处理多种情况的通用扩展方法。函数本身的核心就是一行。
/// <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();
}
Run Code Online (Sandbox Code Playgroud)
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)));
}
Run Code Online (Sandbox Code Playgroud)
我认为这也比当前的答案更有效(事实并非如此)。我必须检查获得 EqualityComparer 是否昂贵,但我愿意对此表示怀疑。
您还可以扩展此函数以接受一个表达式,该表达式将评估要比较包含对象的枚举的属性。
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);
}
Run Code Online (Sandbox Code Playgroud)