我想比较两个数组。。。理想地、有效地。没有什么稀奇古怪的,如果它们是相同的,那就是真的,如果不是,那就是假的。毫不奇怪,比较运算符似乎不起作用。
var a1 = [1,2,3];
var a2 = [1,2,3];
console.log(a1==a2); // Returns false
console.log(JSON.stringify(a1)==JSON.stringify(a2)); // Returns true
JSON对每个数组进行编码,但是否有一种更快或“更好”的方法来简单地比较数组而不必遍历每个值?
我在回答这个问题https://stackoverflow.com/a/10316616/711085(此后已标记为该答案的副本)。在那里,您将发现一个DeepEquals实现,它处理许多情况,例如Map和Set以及数组和对象的任意嵌套。其中对==的非传递性和记录==vs==的讨论尤为重要。
对于OP的特殊问题,如果数组仅由数字、字符串和布尔值组成,而没有NaN,那么对于足够大的数组,最有效的方法是预编译函数:
function areSimpleArraysEqual(a,b) {
// requires inputs be arrays of only Number, String, Boolean, and no NaN.
// will propagate error if either array is undefined.
if (a.length!=b.length)
return false;
for(let i=0; i<a.length; i++)
if (a[i]!==b[i]) // using === equality
return false;
return true;
}
如果一个人的业务逻辑一直附加到数组的末尾,通过检查(a.length>0&&a[a.length-1]!==b[b.length-1])是否返回false;,在一些罕见的情况下,可以实现平均情况O(1)和最坏情况O(N)。
不清楚你所说的“相同”是什么意思。例如,下面的数组a和b是否相同(请注意嵌套数组)?
var a = ["foo", ["bar"]], b = ["foo", ["bar"]];
这里有一个优化的数组比较函数,它使用严格的相等性依次比较每个数组的对应元素,并且不递归比较本身为数组的数组元素,这意味着对于上面的示例,arraysIncore(a,b)将返回false。它适用于一般情况,而基于JSON和join()的解决方案不会:
function arraysIdentical(a, b) {
var i = a.length;
if (i != b.length) return false;
while (i--) {
if (a[i] !== b[i]) return false;
}
return true;
};
所有其他解决方案看起来都很复杂。这可能不是处理所有边缘情况的最有效方法,但它对我来说非常有用。
Array.prototype.includesArray = function(arr) {
return this.map(i => JSON.stringify(i)).includes(JSON.stringify(arr))
}
用法
[[1,1]].includesArray([1,1])
// true
[[1,1]].includesArray([1,1,2])
// false