簡體   English   中英

有關Except擴展方法的新替代的幫助

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM