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

Сравнение массивов с использованием LINQ в С#

У меня есть два массива типа

string[] a = { "a", "b", "c" };
string[] b = { "a", "b", "c" };

Мне нужно сравнить два массива с помощью LINQ.

Сравнение должно происходить только в том случае, если оба массива имеют одинаковый размер. Данные могут быть в любом порядке и возвращать true, если все значения a [] и все значения b [] совпадают.

4b9b3361

Ответ 1

string[] a = { "a", "b" };
string[] b = { "a", "b" };

return (a.Length == b.Length && a.Intersect(b).Count() == a.Length);

После некоторого тестирования производительности:

  • Более 10 000 маленьких строк - 5 мс
  • Более 100 000 маленьких строк - 99 мс
  • Более 1 000 000 маленьких строк - Сред. 601ms
  • Свыше 100 000 ~ 500 символьных строк - 190 мс

Ответ 2

Не уверен в производительности, но это работает.

string[] a = { "a", "b", "c" };
string[] b = { "a", "b", "c" };

bool result = a.SequenceEqual(b);
Assert.AreEqual(true, result);

Однако он не является независимым от заказа, поэтому он не выполняет требования OP.

string[] a = { "a", "b", "c" };
string[] b = { "a", "c", "b" };

bool result = a.SequenceEqual(b);
Assert.AreEqual(false, result);

Ответ 3

Я думаю, что это всегда будет операция O (n log n), поэтому я просто сортирую оба массива и сравниваю их, например. используя SequenceEqual.

Ответ 4

если порядок не имеет значения или могут быть дубликаты, то возможно:

public static class IEnumerableExtensions
{
    public static bool HasSameContentsAs<T>(this ICollection<T> source,
                                            ICollection<T> other)
    {
        if (source.Count != other.Count)
        {
            return false;
        }
        var s = source
            .GroupBy(x => x)
            .ToDictionary(x => x.Key, x => x.Count());
        var o = other
            .GroupBy(x => x)
            .ToDictionary(x => x.Key, x => x.Count());
        int count;
        return s.Count == o.Count &&
               s.All(x => o.TryGetValue(x.Key, out count) &&
                          count == x.Value);
    }
}

использование:

string[] a = { "a", "b", "c" };
string[] b = { "c", "a", "b" };

bool containSame = a.HasSameContentsAs(b);

некоторые варианты использования:

  • разные длины (ожидание false)

    string[] a = { "a", "b", "c" };
    string[] b = { "b", "c" };
    
  • другой порядок (ожидать true)

    string[] a = { "a", "b", "c" };
    string[] b = { "b", "c", "a" };
    

также работает, если входы могут содержать повторяющиеся элементы, хотя из вопроса неясно, нужна ли эта характеристика или нет, учтите:

  • дублированные элементы имеют одинаковое количество (ожидание true)

    string[] a = { "a", "b", "b", "c" };
    string[] b = { "a", "b", "c", "b" };
    
  • дублированные элементы с разными значениями (ожидание false)

    string[] a = { "a", "b", "b", "b", "c" };
    string[] b = { "a", "b", "c", "b", "c" };
    

Ответ 5

IDictionary<int, object> a = new Dictionary<int, object>();
IDictionary<int, object> b = new Dictionary<int, object>();
a.Add(1, "1");
a.Add(2, 2);
a.Add(3, "3");

b.Add(3, "3");
b.Add(1, "1");
b.Add(2, 2);

Console.WriteLine(a.All(i => b.Contains(i)) && b.All(i => a.Contains(i)));

Ответ 6

Это правильно работает с дубликатами и проверяет каждый элемент

a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any()