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

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


当前回答

var er = [{id:"23",name:"23222"}, {id:"222",name:"23222222"}];
var er2 = [{id:"23",name:"23222"}, {id:"222",name:"23222222"}];

var result = (JSON.stringify(er) == JSON.stringify(er2)); // true

如果不更改每个条目的属性顺序,那么它可以很好地处理json对象。

var er = [{name:"23222",id:"23"}, {id:"222",name:"23222222"}];
var er2 = [{id:"23",name:"23222"}, {id:"222",name:"23222222"}];

var result = (JSON.stringify(er) == JSON.stringify(er2)); // false  

但是数组的每个条目中只有一个属性或值,这将很好地工作。

其他回答

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

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

这是一个棘手的隐式数组相等性检查,但可以在连贯数组到字符串之后立即处理该任务。

var a1 = [1, 2, 3];
var a2 = [1, 2, 3];
var isEqual = a1 <= a2 && a1 >= a2; // true

使用数字/字符串/数组/对象的Ré草书cmp函数

<脚本>var cmp=函数(元素,目标){if(元素类型!==目标类型){return false;}否则if(typeof element==“object”&&(!target||!element)){返回目标==元素;}else if(元素类型==“对象”){var keys_element=对象.keys(元素);var keys_target=对象.keys(目标);如果(keys_element.length!==keys_target.length){return false;}其他的{对于(var i=0;i<keys_element.length;i++){如果(keys_element[i]!==keys_target[i])return false;if(!cmp(元素[keys_element[i]],目标[keys_target[i]]))return false;}返回true;}}其他的{返回元素==目标;}};console.log(cmp({键1:3,key2:“字符串”,key3:[4,“45”,{key4:[5,“6”,false,null,{v:1}]}]}, {键1:3,key2:“字符串”,key3:[4,“45”,{key4:[5,“6”,false,null,{v:1}]}]})); // 真的console.log(cmp({键1:3,key2:“字符串”,key3:[4,“45”,{key4:[5,“6”,false,null,{v:1}]}]}, {键1:3,key2:“字符串”,键3:[4,“45”,{键4:[5,“6”,未定义,null,{v:1}]}]})); // 假的</script>

使用过滤器和箭头函数的另一种方法

arrOne.length === arrTwo.length && arrOne.filter((currVal, idx) => currVal !== arrTwo[idx]).length === 0

根据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/