هل هناك طريقة للحصول على الفرق بين اثنين من مجموعات من الكائنات في C #

StackOverflow https://stackoverflow.com/questions/806152

  •  03-07-2019
  •  | 
  •  

سؤال

وأريد الحصول على الفرق بين مجموعتين من [إينتس] في ج #. وبالنظر S1 و S2 أريد أن أعود تلك [إينتس] التي هي في S1 و S2 لا. يمكنني فعل شيء مثل:

    List<int> s1 = new List<int>();
    List<int> s2 = new List<int>();

    foreach (int i in s1)
    {
        if (s1.Contains(i))
        {
            //
        }
        else
        {
            //
        }
    }

ولكن أنا أتساءل عما اذا كان أي شخص يمكن أن نشير إلى شيء أنظف. وأود أن تفعل شيئا مثل

List<int> omitted = s1.Difference(s2);

ولست متأكدا إذا كان هناك طريقة القائمة أو LINQ بناء أن أي شخص قد تكون قادرة على نشير؟ شكرا لك.

هل كانت مفيدة؟

المحلول

وأعتقد أنك تريد HashSet.Except . وهذا هو، بدلا من استخدام قوائم، HashSets الاستخدام، ومن ثم كانت العملية المتاحة. هذا هو نوع من الأفضل لو ما كنت تمثل حقا "تعيين" على أي حال. (إذا كان لديك بالفعل القائمة، يمكنك فقط إنشاء "HashSet الجديد" للخروج منه.)

نصائح أخرى

IEnumerable<T> a, b;

var added = a.Except(b);
var removed = b.Except(a);
List<int> s1 = new List<int>();
List<int> s2 = new List<int>();

return sl.FindAll( i => !s2.Contains(i) )
from x in s1
where ! s2.contains(x)
select x

وفيما يلي طريقتين التمديد التي قد تأتي في متناول يدي عندما كنت في حاجة للعثور على الخلافات بين اثنين من غير مرتبة IEnumerable (هو أكثر أو أقل نفس الإجابة التي قدمها المجمع leppie إلى طرق الإرشاد):

public class EnumerableDifferences<T>
{
    public IEnumerable<T> Added { get; }
    public IEnumerable<T> Removed { get; }

    public EnumerableDifferences(IEnumerable<T> added, IEnumerable<T> removed)
    {
        Added = added;
        Removed = removed;
    }
}

public static class EnumerableExtensions
{
    public static HashSet<TSource> ToHashSet<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
    {
        return new HashSet<TSource>(source, comparer);
    }

    public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TSource> second, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer = null)
    {
        return first
            .ExceptBy(keySelector, second.Select(keySelector), keyComparer);
    }

    public static IEnumerable<TSource> ExceptBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, IEnumerable<TKey> keys, IEqualityComparer<TKey> keyComparer = null)
    {
        var secondKeys = keys.ToHashSet(keyComparer);

        foreach (var firstItem in source)
        {
            var firstItemKey = keySelector(firstItem);

            if (!secondKeys.Contains(firstItemKey))
            {
                yield return firstItem;
            }
        }
    }

    public static EnumerableDifferences<TSource> DifferencesBy<TSource, TKey>(this IEnumerable<TSource> first, IEnumerable<TSource> second, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> keyComparer = null)
    {
        keyComparer = keyComparer ?? EqualityComparer<TKey>.Default;

        var removed = first.ExceptBy(second, keySelector, keyComparer);
        var added = second.ExceptBy(first, keySelector, keyComparer);

        var result = new EnumerableDifferences<TSource>(added, removed);

        return result;
    }

    public static EnumerableDifferences<TSource> Differences<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second, IEqualityComparer<TSource> comparer = null)
    {
        return first
            .DifferencesBy(second, x => x, comparer);
    }
}

public static class Program
{
    public static void Main(params string[] args)
    {
        var l1 = new[] { 'a', 'b', 'c' };
        var l2 = new[] { 'a', 'd', 'c' };

        var result = l1.Differences(l2);

        Console.ReadKey();
    }
}

وAPI آخر مفيد، احصل على الفرق متماثل:

HashSet.SymmetricExceptWith ()

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top