Сравнение массивов с использованием LINQ в С#
У меня есть два массива типа
string[] a = { "a", "b", "c" };
string[] b = { "a", "b", "c" };
Мне нужно сравнить два массива с помощью LINQ.
Сравнение должно происходить только в том случае, если оба массива имеют одинаковый размер. Данные могут быть в любом порядке и возвращать true, если все значения a [] и все значения b [] совпадают.
Ответы
Ответ 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()