在C#中使用LINQ比较数组
我有两个数组
string[] a = { "a", "b", "c" }; string[] b = { "a", "b", "c" };
我需要使用LINQ比较两个数组。
仅当两个arrays具有相同大小时才应进行比较。 数据可以是任何顺序,如果[]的所有值和b []的所有值相同,则仍然返回true。
string[] a = { "a", "b" }; string[] b = { "a", "b" }; return (a.Length == b.Length && a.Intersect(b).Count() == a.Length);
经过一些性能测试:
- 超过10,000个小字符串 – 5ms
- 超过100,000个小字符串 – 99ms
- 超过1,000,000个小字符串 – 平均 601ms
- 超过100,000~500个字符串 – 190ms
不确定性能,但这似乎工作。
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);
我认为这将永远是一个O(n log n)操作,所以我只是对两个数组进行排序并比较它们,例如使用SequenceEqual。
如果订单无关紧要或者可能存在重复,那么可能:
public static class IEnumerableExtensions { public static bool HasSameContentsAs(this ICollection source, ICollection 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);
一些用例:
-
不同的长度(期望假)
string[] a = { "a", "b", "c" }; string[] b = { "b", "c" };
-
不同的顺序(期望为真)
string[] a = { "a", "b", "c" }; string[] b = { "b", "c", "a" };
如果输入可以包含重复项目也可以工作,但是从问题中是否需要该特征是不明确的,请考虑:
-
重复项目具有相同的计数(期望为真)
string[] a = { "a", "b", "b", "c" }; string[] b = { "a", "b", "c", "b" };
-
具有不同计数的重复项目(期望为假)
string[] a = { "a", "b", "b", "b", "c" }; string[] b = { "a", "b", "c", "b", "c" };
IDictionary a = new Dictionary(); IDictionary b = new Dictionary(); 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)));
这适用于重复项并检查每个元素
a.Length == b.Length && !a.Where((t, i) => t != b[i]).Any()