[英]Help with new override for Except extension method
我想為IEnumerable
編寫一個Except
擴展方法的新替代方法,該方法可以采用比較器內聯而不是使用IEqualityComparer。
A,B是引用類型的集合。
像這樣:
A: [1, A], [2, A], [3, A]
B: [3, B], [4, B], [5, B]
C = A.Except(B, (a,b) => a.Id == b.Id);
C: [1, A], [2, A]
我想知道您是否可以通過該方法的代碼幫助我。
public static class IEnumerableExntesion
{
public IEnumerable<T> Except<T>(this IEnumerable<T> source,
IEnumerable<T> second,
Func<T, T, bool> predicate)
{
}
}
我在想:
return source.Where (s => !second.Any(p => p.Id == s.Id));
但是實際上我無法使用所傳遞的謂詞將其轉換為通用解決方案!
任何幫助!
這應該工作:
return source.Where(s => !second.Any(p => predicate(s, p))
return source.Where(s => !second.Any(p => predicate(p, s)));
您需要使用謂詞進行比較還是可以使用投影來比較投影值? 如果是這樣,那么您可以使用某種ExceptBy
方法:
var c = a.ExceptBy(b, x => x.Id);
var r = p.ExceptBy(q, x => x.Name, StringComparer.OrdinalIgnoreCase);
// ...
public static class EnumerableExtensions
{
public static IEnumerable<TSource> ExceptBy<TSource, TKey>(
this IEnumerable<TSource> first, IEnumerable<TSource> second,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> keyComparer = null)
{
if (first == null) throw new ArgumentNullException("first");
if (second == null) throw new ArgumentNullException("second");
if (keySelector == null) throw new ArgumentNullException("keySelector");
return first.ExceptByIterator(second, keySelector, keyComparer);
}
private static IEnumerable<TSource> ExceptByIterator<TSource, TKey>(
this IEnumerable<TSource> first, IEnumerable<TSource> second,
Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer)
{
var keys = new HashSet<TKey>(second.Select(keySelector), keyComparer);
foreach (TSource item in first)
{
if (keys.Add(keySelector(item)))
yield return item;
}
}
}
我會改用您傳遞的Func<T,T,bool>
創建通用的IEqualityComparer
並將其傳遞給常規的Except
:
public class PredicateEqualityComparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> _predicate;
public PredicateEqualityComparer(Func<T, T, bool> predicate)
{
_predicate = predicate;
}
public bool Equals(T x, T y)
{
return _predicate(x, y);
}
public int GetHashCode(T x)
{
return 0;
}
}
您的擴展方法:
public static class IEnumerableExntesion
{
public IEnumerable<T> Except<T>(this IEnumerable<T> source,
IEnumerable<T> second,
Func<T, T, bool> predicate)
{
return source.Except(second, new PredicateEqualityComparer(predicate));
}
}
請注意,我有一個GetHashCode
實現的存根,最好正確實現它,但是您必須為此傳遞另一個委托。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.