Подтвердить что ты не робот

Сравните два объекта .NET Array

Я пытаюсь сравнить два .NET-массива. Вот очевидная реализация для сравнения массивов байтов:

bool AreEqual(byte[] a, byte[] b){
    if(a.Length != b.Length)
        return false;
    for(int i = 0; i < a.Length; i++)
        if(a[i] != b[i])
            return false;

    return true;
}

Более совершенный подход можно увидеть здесь (через Google).

  • Каков самый простой способ (используя меньше код, но читаемый), чтобы сравнить два .NET массивы?
  • Что является наиболее эффективным способом сравнить два массива .NET?
4b9b3361

Ответ 1

Подход Кэти кажется мне хорошим. Я бы лично разрешил конкретному указателю:

bool AreEqual<T>(T[] a, T[] b)
{
    return AreEqual(a, b, EqualityComparer<T>.Default);
}

bool AreEqual<T>(T[] a, T[] b, IEqualityComparer<T> comparer)
{
    // Handle identity comparison, including comparing nulls
    if (a == b)
    {
        return true;
    }

    if (a == null || b == null)
    {
        return false;
    }

    if(a.Length != b.Length)
    {
        return false;
    }

    for(int i = 0; i < a.Length; i++)
    {
        if(!comparer.Equals(a[i], b[i]))
        {
            return false;
        }
    }
    return true;
}

SequenceEqual, упомянутый CMS, хорош, но из-за его общности над IEnumerable<T> я не думаю, что он может сделать "раньше", если длина не равна. (Возможно, он проверяет обе последовательности, реализующие IList, хотя, чтобы напрямую проверять Count.) Вы могли бы обобщить немного больше, чтобы использовать IList<T>

bool AreEqual<T>(IList<T> a, IList<T> b, IEqualityComparer<T> comparer)
{
    if(a.Count != b.Count)
    {
        return false;
    }
    for(int i = 0; i < a.Count; i++)
    {
        if(!comparer.Equals(a[i], b[i]))
        {
            return false;
        }
    }
    return true;
}

Прямая версия массива, вероятно, будет наиболее эффективной - добавление общности и абстракции обычно сказывается на производительности, хотя значительная ли она будет зависеть от вашего приложения.

Ответ 2

Вы можете использовать SequenceEqual:

string[] a = { "1", "2", "3" };
string[] b = { "1", "2", "3" };

bool areEqual = a.SequenceEqual(b); // true


string[] c = { "1", "2", "5" };
areEqual = a.SequenceEqual(c);      // false

Ответ 3

С появлением .NET 4 вы можете использовать метод Equals(), предоставляемый явным образом реализованным интерфейсом .NET arrays IStructuralEquatable. Тогда код может выглядеть так (я переписал пример CMS):

string[] a = { "1", "2", "3" };
string[] b = { "1", "2", "3" };
bool result = ((IStructuralEquatable)a).Equals(b, StructuralComparisons.StructuralEqualityComparer);
// result evaluates to true.

(IStructuralEquatable также реализуется в Tuples (также новый в .NET 4).)

Ответ 4

Может быть, что-то вроде этого?

static bool AreEqual<T>(T[] a, T[] b) 
{
    bool areEqual = false ;
    T[] result = a.Intersect(b.AsEnumerable()).ToArray();
    areEqual = (result.Length == a.Length) && (result.Length == b.Length);
    return areEqual;
}

Я не уверен в производительности, поразившей этого.

ИЗМЕНИТЬ

пересмотренная версия с учетом рекомендаций Джона:

    static bool AreEqual<T>(T[] a, T[] b) 
    {
        return a.SequenceEqual(b);
    }