我想比较两个数组。。。理想地、有效地。没有什么稀奇古怪的,如果它们是相同的,那就是真的,如果不是,那就是假的。毫不奇怪,比较运算符似乎不起作用。

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对每个数组进行编码,但是否有一种更快或“更好”的方法来简单地比较数组而不必遍历每个值?


当前回答

本着原问题的精神:

我想比较两个数组。。。理想地、有效地。没有什么想象,如果它们是相同的,则为真,如果不是,则为假。

我一直在对这里提出的一些更简单的建议进行性能测试,结果如下(从快到慢):

而Tim Down(67%)

var i = a1.length;
while (i--) {
    if (a1[i] !== a2[i]) return false;
}
return true

每(69%)用户2782196

a1.every((v,i)=> v === a2[i]);

DEI减少(74%)

a1.reduce((a, b) => a && a2.includes(b), true);

Gaizka Allende&vivek的join&toString(78%)

a1.join('') === a2.join('');

a1.toString() === a2.toString();

Victor Palomo创作的半到字符串(90%)

a1 == a2.toString();

radtek的stringify(100%)

JSON.stringify(a1) === JSON.stringify(a2);

注意,下面的示例假设数组是排序的,一维数组。对于一个常见的基准测试,长度比较已被删除(将a1.length==a2.length添加到任何建议中,您将获得约10%的性能提升)。选择最适合您的解决方案,了解每种解决方案的速度和局限性。

其他回答

如果使用Mocha这样的测试框架和Chai断言库,可以使用深度相等来比较数组。

expect(a1).to.deep.equal(a2)

只有当数组在相应的索引处具有相等的元素时,才会返回true。

这将比较2个未排序的数组:

function areEqual(a, b) {
  if ( a.length != b.length) {
    return false;
  }
  return a.filter(function(i) {
    return !b.includes(i);
  }).length === 0;  
}

将TomášZa的想法扩展到。Tomas的Array.prototype.compare实际上应该被称为Array.prototy.compare。

它传递:

[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 2]]) === false;
[1, "2,3"].compareIdentical ([1, 2, 3]) === false;
[1, 2, [3, 4]].compareIdentical ([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].compareIdentical ([1, 2, 1, 2]) === true;

但在以下情况下失败:

[[1, 2, [3, 2]],1, 2, [3, 2]].compareIdentical([1, 2, [3, 2],[1, 2, [3, 2]]])

以下是更好的(我认为)版本:

Array.prototype.compare = function (array) {
    // if the other array is a falsy value, return
    if (!array)
        return false;

    // compare lengths - can save a lot of time
    if (this.length != array.length)
        return false;

    this.sort();
    array.sort();
    for (var i = 0; i < this.length; i++) {
        // Check if we have nested arrays
        if (this[i] instanceof Array && array[i] instanceof Array) {
            // recurse into the nested arrays
            if (!this[i].compare(array[i]))
                return false;
        }
        else if (this[i] != array[i]) {
            // Warning - two different object instances will never be equal: {x:20} != {x:20}
            return false;
        }
    }
    return true;
}

http://jsfiddle.net/igos/bcfCY/

令人惊讶的是,没有人提出解决办法

const a = [1, 2, 3]
const b = [1, 2, 3, 4]
a.find((v,i) => v !== b[i])

这里的好处是,它不会比较所有值,而是查找第一次出现的值,并尽早结束循环。换句话说,它不是问“两个数组相等吗?”而是问“一个数组与另一个数组不同吗?”。

绩效基准排名第三https://jsben.ch/TgFrA

记住,顺序很重要,a.find(…)!==b.find(…),可以通过a.length==b.length进行检查

if (a.length === b.length && a.find((v,i) => v !== b[i]) === undefined) {
  // equal
}

本着原问题的精神:

我想比较两个数组。。。理想地、有效地。没有什么想象,如果它们是相同的,则为真,如果不是,则为假。

我一直在对这里提出的一些更简单的建议进行性能测试,结果如下(从快到慢):

而Tim Down(67%)

var i = a1.length;
while (i--) {
    if (a1[i] !== a2[i]) return false;
}
return true

每(69%)用户2782196

a1.every((v,i)=> v === a2[i]);

DEI减少(74%)

a1.reduce((a, b) => a && a2.includes(b), true);

Gaizka Allende&vivek的join&toString(78%)

a1.join('') === a2.join('');

a1.toString() === a2.toString();

Victor Palomo创作的半到字符串(90%)

a1 == a2.toString();

radtek的stringify(100%)

JSON.stringify(a1) === JSON.stringify(a2);

注意,下面的示例假设数组是排序的,一维数组。对于一个常见的基准测试,长度比较已被删除(将a1.length==a2.length添加到任何建议中,您将获得约10%的性能提升)。选择最适合您的解决方案,了解每种解决方案的速度和局限性。