سریعترین راه برای مقایسه دو لیست عظیم در سی شارپ #C

سریعترین روش  (که کمترین منابع سیستم را درگیر می کند) برای مقایسه دو لیست بسیار عظیم بیش از (> 50،۰۰۰ مورد) چیست ؟ و اگر دو لیست مشابه داشته باشیم که در نهایت بخواهیم آنها را مقایسه کنیم چطور ؟

فرض کنیم شرایط مقایسه موارد زیر باشد :

مواردی که در لیست اول نشان داده می شوند اما در لیست دوم نشان داده نمی شوند
مواردی که در لیست دوم نشان داده می شوند اما در لیست اول وجود ندارد

var list1 = list.Where(i => !list2.Contains(i)).ToList();
var list2 = list2.Where(i => !list.Contains(i)).ToList();

روش اول

در بهترین و ساده ترین حالت برای پاسخ به این سوال می توانید از except استفاده کنید :

پلتفرم بوی اجرا شدن خروجی صحیح قطعه کد زیر را تایید می کند

قطعه کدی که در زیر مشاهده می کنید توسط برنامه کامپایلر به جهت تست آزمایش شده و خروجی صحیح مدنظر را بدست آورد.

var firstNotSecond = list1.Except(list2).ToList();
var secondNotFirst = list2.Except(list1).ToList();

اما اگر می خواهید اینها را با هم ترکیب کنید ، می توانید یک متد با موارد بالا و سپس یک دستور بازگشت ایجاد کنید:

return !firstNotSecond.Any() && !secondNotFirst.Any();

روش دوم

قطعه کدی داریم که می توانید از join استفاده کنید :

string.Join("",List1) != string.Join("", List2)

روش سوم

using System.Collections.Generic;
using System.Linq;

namespace YourProject.Extensions
{
    public static class ListExtensions
    {
        public static bool SetwiseEquivalentTo<T>(this List<T> list, List<T> other)
            where T: IEquatable<T>
        {
            if (list.Except(other).Any())
                return false;
            if (other.Except(list).Any())
                return false;
            return true;
        }
    }
}

بعضی اوقات فقط باید بدانید که دو لیست متفاوت هستند و اینکه این تفاوت ها در چیست. در این صورت ، می توانید از قطعه کد زیر در پروژه خود استفاده کنید . فقط توجه داشته باشید که اشیا listed ذکر شده شما باید IEquatable را اجرا کنند!

public sealed class Car : IEquatable<Car>
{
    public Price Price { get; }
    public List<Component> Components { get; }

    ...
    public override bool Equals(object obj)
        => obj is Car other && Equals(other);

    public bool Equals(Car other)
        => Price == other.Price
            && Components.SetwiseEquivalentTo(other.Components);

    public override int GetHashCode()
        => Components.Aggregate(
            Price.GetHashCode(),
            (code, next) => code ^ next.GetHashCode()); // Bitwise XOR
}

روش چهارم

اگر فقط می خواهید نتایج را با یکدیگر ترکیب کنید از کد زیر استفاده کنید :

var set1 = new HashSet<T>(list1);
var set2 = new HashSet<T>(list2);
var areEqual = set1.SetEquals(set2);

روش پنجم

از این کد برای مقایسه دو لیستی استفاده کنید که دارای میلیون ها رکورد است.

استفاده از این قطعه کد زمان زیادی نخواهد برد (پلتفرم بوی این مورد را تایید نمی کند – تست کنید ! )

private List<string> Contains(List<string> list1, List<string> list2)
{
    List<string> result = new List<string>();

    result.AddRange(list1.Except(list2, StringComparer.OrdinalIgnoreCase));
    result.AddRange(list2.Except(list1, StringComparer.OrdinalIgnoreCase));

    return result;
}

روش ششم

public class EquatableList<T> : List<T>, IEquatable<EquatableList<T>> where    T : IEquatable<T>

public new Boolean Contains(T element)
{
    return this.Any(t => t.Equals(element));
}
public Boolean Equals(EquatableList<T> list)
{
    if (list == null) return false;
    return this.All(list.Contains) && list.All(this.Contains);
}

روش هفتم

اگر می خواهید نتایج به حروف کوچک حساس نشوند ، قطعه کد زیر را استفاده کنید :

List<string> list1 = new List<string> { "a.dll", "b1.dll" };
List<string> list2 = new List<string> { "A.dll", "b2.dll" };
var firstNotSecond = list1.Except(list2, StringComparer.OrdinalIgnoreCase).ToList();
var secondNotFirst = list2.Except(list1, StringComparer.OrdinalIgnoreCase).ToList();

 

آیا این نوشته برای شما مفید بود ؟

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *