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

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%的性能提升)。选择最适合您的解决方案,了解每种解决方案的速度和局限性。

其他回答

递归在NESTED数组上工作(&W):

function ArrEQ(a1,a2){
   return( 
        //:Are both elements arrays?
        Array.isArray(a1)&&Array.isArray(a2) 
        ?
        //:Yes: Test each entry for equality:
        a1.every((v,i)=>(ArrEQ(v,a2[i])))
        :
        //:No: Simple Comparison:
        (a1===a2)
   );;
};;

console.log( "Works With Nested Arrays:" );
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]],
    [1,2,3,[4,5,[6,"SAME/IDENTICAL"]]]
));;     
console.log( ArrEQ( 
    [1,2,3,[4,5,[6,"DIFFERENT:APPLES" ]]],
    [1,2,3,[4,5,[6,"DIFFERENT:ORANGES"]]]
));;  

虽然这只适用于标量数组(请参见下面的注释),但代码很短:

array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})

与上文相同,但在ECMAScript 6/CoffeeScript/TypeScript中使用箭头函数:

array1.length === array2.length && array1.every((value, index) => value === array2[index])

(注意:这里的“scalar”表示可以使用==直接比较的值。因此:数字、字符串、引用对象、引用函数。有关比较运算符的更多信息,请参阅MDN引用)。

更新

根据我在评论中看到的内容,对数组进行排序和比较可能会得到准确的结果:

const array2Sorted = array2.slice().sort();
array1.length === array2.length && array1.slice().sort().every(function(value, index) {
    return value === array2Sorted[index];
});

Eg:

array1 = [2,3,1,4];
array2 = [1,2,3,4];

然后上述代码将返回true

与嵌套数组一起使用MULTIPLE参数:

//:Return true if all of the arrays equal.
//:Works with nested arrays.
function AllArrEQ(...arrays){
    for(var i = 0; i < (arrays.length-1); i++ ){
        var a1 = arrays[i+0];
        var a2 = arrays[i+1];
        var res =( 
            //:Are both elements arrays?
            Array.isArray(a1)&&Array.isArray(a2) 
            ?
            //:Yes: Compare Each Sub-Array:
            //:v==a1[i]
            a1.every((v,i)=>(AllArrEQ(v,a2[i])))
            :
            //:No: Simple Comparison:
            (a1===a2)
        );;
        if(!res){return false;}
    };;
    return( true );
};;

console.log( AllArrEQ( 
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
        [1,2,3,[4,5,[6,"ALL_EQUAL"   ]]],
));; 

此外,我还根据需要将Thomas的解决方案转换为无需排序的比较。

Array.prototype.equalsFreeOrder = function (array) {
    var isThisElemExist;
    if (!array)
        return false;

    if (this.length != array.length)
        return false;

    for (var i = 0; i < this.length; i++) {
        isThisElemExist = false;
        for (var k = 0; k < this.length; k++) {
            if (this[i] instanceof Array && array[k] instanceof Array) {
                if (this[i].equalsFreeOrder(array[k]))
                    isThisElemExist = true;
            }
            else if (this[i] == array[k]) {
                isThisElemExist = true;
            }
        }
        if (!isThisElemExist)
            return false;
    }
    return true;
}

代码高尔夫

有很多答案表明如何有效地比较数组。

以下是比较两个int或(字符串)数组的最短方法,以代码字节为单位。

常量a=[1,2,3]常量b=[1,2,3]console.log(“1.”,a.join()==b.join(())console.log(“2.”,a.join()==[].join())console.log(“3.”,1+a==1+b)console.log(“4.”,1+[]==1+b)//甚至更短console.log(“4.b)”,a==“”+b)//误报(见缺陷)console.log(“5.”,1+[“3”]==1+[3])//类型差异console.log(“6.”,1+[“1,2”]==1+[“1”,“2”])

解释

这是因为当使用+运算符时,类型会自动转换为允许串联。在这种情况下,1和[1,2,3]都被转换为字符串。

在内部,JavaScript使用[1,2,3].join()将数组转换为字符串,然后将它们相加,得到11,2,3。在两个数组上执行此操作时,可以简单地使用==或==来比较两个字符串。

缺陷

使用此技术,比较不关心要比较的数组中的元素是否属于不同类型。由于字符串转换,[1,2]将等于[“1”,“2”]。

编辑:正如评论中指出的,比较字符串数组可能会产生误报,例如[“1,2”]等于[“1”,“2”]。如果您确信这些情况从未发生过(例如,在许多代码高尔夫挑战中),这一点就不重要了。

免责声明

虽然这对于代码高尔夫很有用,但可能不应该在生产代码中使用。指出的两个缺陷也无助于此。