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

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


当前回答

我会这样做:

[2,3,4,5] == [2,3,4,5].toString()

当您使用“==”运算符时,javascript检查值(左侧和右侧)是否是相同的类型,如果是不同的,javascript尝试将两边转换为相同的类型。

Array == String

Array具有toString方法,因此javascript使用它将它们转换为相同的类型,工作方式如下:

[2,3,4,5].toString() == [2,3,4,5].toString()

其他回答

我在回答这个问题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)。

此函数比较两个任意形状和尺寸的数组:

function equals(a1, a2) {

    if (!Array.isArray(a1) || !Array.isArray(a2)) {
        throw new Error("Arguments to function equals(a1, a2) must be arrays.");
    }

    if (a1.length !== a2.length) {
        return false;
    }

    for (var i=0; i<a1.length; i++) {
        if (Array.isArray(a1[i]) && Array.isArray(a2[i])) {
            if (equals(a1[i], a2[i])) {
                continue;
            } else {
                return false;
            }
        } else {
            if (a1[i] !== a2[i]) {
                return false;
            }
        }
    }

    return true;
}

此外,我还根据需要将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;
}

如果它们是两个数字或字符串数组,这是一个快速的单行数组

const array1 = [1, 2, 3];
const array2 = [1, 3, 4];
console.log(array1.join(',') === array2.join(',')) //false

const array3 = [1, 2, 3];
const array4 = [1, 2, 3];
console.log(array3.join(',') === array4.join(',')) //true

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

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