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

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


当前回答

代码高尔夫

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

以下是比较两个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”]。如果您确信这些情况从未发生过(例如,在许多代码高尔夫挑战中),这一点就不重要了。

免责声明

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

其他回答

我认为这是使用JSON字符串最简单的方法,在某些情况下可能是最好的解决方案:

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

这将对象a1和a2转换为字符串,以便对它们进行比较。在大多数情况下,顺序很重要,因为它可以使用上面答案之一中所示的排序算法对对象进行排序。

请注意,您不再比较对象,而是比较对象的字符串表示形式。这可能不是你想要的。

let equals = (LHS, RHS) => {
    if (!(LHS instanceof Array)) return "false > L.H.S is't an array";
    if (!(RHS instanceof Array)) return "false > R.H.S is't an array";
    if (LHS.length != RHS.length) return false;
    let to_string = x => JSON.stringify(x.sort((a, b) => a - b));
    return to_string(LHS) == to_string(RHS);
  };

let l = console.log
l(equals([5,3,2],[3,2,5]))    // true
l(equals([3,2,5,3],[3,2,5]))  // false

一种简单的方法:

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;
}

我想出了另一种方法。使用join(“”)将它们更改为字符串,然后比较两个字符串:

var a1_str = a1.join(''),
    a2_str = a2.join('');

if (a2_str === a1_str) {}

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

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;
}