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

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


当前回答

根据TomášZato的回答,我同意仅迭代数组是最快的。此外(就像其他人已经说过的那样),函数应该被称为equals/equal,而不是compare。考虑到这一点,我修改了该函数,以处理比较数组的相似性(即它们具有相同的元素,但没有顺序),以供个人使用,并认为我将把它放在这里让大家看到。

Array.prototype.equals = function (array, strict) {
    if (!array)
        return false;

    if (arguments.length == 1)
        strict = true;

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

    for (var i = 0; i < this.length; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i], strict))
                return false;
        }
        else if (strict && this[i] != array[i]) {
            return false;
        }
        else if (!strict) {
            return this.sort().equals(array.sort(), true);
        }
    }
    return true;
}

此函数接受默认为true的strict附加参数。这个严格的参数定义数组是否需要在内容和这些内容的顺序上完全相等,或者仅仅包含相同的内容。

例子:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3];  // Loosely equal to 1
var arr3 = [2, 2, 3, 4];  // Not equal to 1
var arr4 = [1, 2, 3, 4];  // Strictly equal to 1

arr1.equals(arr2);         // false
arr1.equals(arr2, false);  // true
arr1.equals(arr3);         // false
arr1.equals(arr3, false);  // false
arr1.equals(arr4);         // true
arr1.equals(arr4, false);  // true

我还编写了一个函数的快速jsfiddle,以及这个示例:http://jsfiddle.net/Roundaround/DLkxX/

其他回答

已经有一些很好的答案了。但我想分享另一个在比较数组时被证明是可靠的想法。我们可以使用JSON.stringify()比较两个数组。它将从数组中创建一个字符串,从而比较从两个数组中获得的两个字符串以获得相等

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:1},2]) //true

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},2]) //false

JSON.stringify([1,{a:1},2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:1},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //false

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4],2]) //true

JSON.stringify([1,{a:2},[3,4],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[4]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //false

JSON.stringify([1,{a:2},[3,4,[5]],2]) == JSON.stringify([1,{a:2},[3,4,[5]],2]) //true

2020年推出了第一阶段的建议,通过在语言中添加Array.prototype.equals,可以方便地比较数组。这就是它的工作方式,没有任何库、猴痘或任何其他代码:

[1, 2, 3].equals([1, 2, 3]) // evaluates to true
[1, 2, undefined].equals([1, 2, 3]) // evaluates to false
[1, [2, [3, 4]]].equals([1, [2, [3, 4]]]) // evaluates to true

到目前为止,这只是一个初步的建议——TC39现在将“花时间研究问题空间、解决方案和跨领域关注”。如果它进入了第二阶段,那么它很有可能最终融入到语言中。

根据TomášZato的回答,我同意仅迭代数组是最快的。此外(就像其他人已经说过的那样),函数应该被称为equals/equal,而不是compare。考虑到这一点,我修改了该函数,以处理比较数组的相似性(即它们具有相同的元素,但没有顺序),以供个人使用,并认为我将把它放在这里让大家看到。

Array.prototype.equals = function (array, strict) {
    if (!array)
        return false;

    if (arguments.length == 1)
        strict = true;

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

    for (var i = 0; i < this.length; i++) {
        if (this[i] instanceof Array && array[i] instanceof Array) {
            if (!this[i].equals(array[i], strict))
                return false;
        }
        else if (strict && this[i] != array[i]) {
            return false;
        }
        else if (!strict) {
            return this.sort().equals(array.sort(), true);
        }
    }
    return true;
}

此函数接受默认为true的strict附加参数。这个严格的参数定义数组是否需要在内容和这些内容的顺序上完全相等,或者仅仅包含相同的内容。

例子:

var arr1 = [1, 2, 3, 4];
var arr2 = [2, 1, 4, 3];  // Loosely equal to 1
var arr3 = [2, 2, 3, 4];  // Not equal to 1
var arr4 = [1, 2, 3, 4];  // Strictly equal to 1

arr1.equals(arr2);         // false
arr1.equals(arr2, false);  // true
arr1.equals(arr3);         // false
arr1.equals(arr3, false);  // false
arr1.equals(arr4);         // true
arr1.equals(arr4, false);  // true

我还编写了一个函数的快速jsfiddle,以及这个示例:http://jsfiddle.net/Roundaround/DLkxX/

一种简单的方法:

function equals(a, b) {
    if ((a && !b) || (!a && b) || (!a && !b) || (a.length !== b.length)) {
        return false;
    }

    var isDifferent = a.some(function (element, index) { 
        return element !== b[index];
    });

    return !isDifferent;
}

递归在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"]]]
));;