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

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


当前回答

以下是我的解决方案:

/**
 * Tests two data structures for equality
 * @param {object} x
 * @param {object} y
 * @returns {boolean}
 */
var equal = function(x, y) {
    if (typeof x !== typeof y) return false;
    if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
    if (typeof x === 'object') {
        for (var p in x) if (x.hasOwnProperty(p)) {
            if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
            if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
            if (typeof x[p] !== typeof y[p]) return false;
            if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
            if (x[p] !== y[p]) return false;
        }
    } else return x === y;
    return true;
};

适用于任何嵌套的数据结构,显然忽略了对象的方法。甚至不要考虑用这个方法扩展Object.prototype,当我尝试过一次时,jQuery坏了;)

对于大多数阵列,它仍然比大多数串行化解决方案更快。这可能是对象记录数组最快的比较方法。

其他回答

一种简单的方法:

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

您可以简单地使用lodash库中的isEqual。它非常高效和干净。

import isEqual from "lodash/isEqual";

const isTwoArraysEqual = isEqual(array1, array2);

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

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

这里有一种未排序数组和自定义比较的可能性:

    const array1 = [1,3,2,4,5];
    const array2 = [1,3,2,4,5];
    
    const isInArray1 = array1.every(item => array2.find(item2 => item===item2))
    const isInArray2 = array2.every(item => array1.find(item2 => item===item2))
    
    const isSameArray = array1.length === array2.length && isInArray1 && isInArray2
    
    console.log(isSameArray); //true

以下是我的解决方案:

/**
 * Tests two data structures for equality
 * @param {object} x
 * @param {object} y
 * @returns {boolean}
 */
var equal = function(x, y) {
    if (typeof x !== typeof y) return false;
    if (x instanceof Array && y instanceof Array && x.length !== y.length) return false;
    if (typeof x === 'object') {
        for (var p in x) if (x.hasOwnProperty(p)) {
            if (typeof x[p] === 'function' && typeof y[p] === 'function') continue;
            if (x[p] instanceof Array && y[p] instanceof Array && x[p].length !== y[p].length) return false;
            if (typeof x[p] !== typeof y[p]) return false;
            if (typeof x[p] === 'object' && typeof y[p] === 'object') { if (!equal(x[p], y[p])) return false; } else
            if (x[p] !== y[p]) return false;
        }
    } else return x === y;
    return true;
};

适用于任何嵌套的数据结构,显然忽略了对象的方法。甚至不要考虑用这个方法扩展Object.prototype,当我尝试过一次时,jQuery坏了;)

对于大多数阵列,它仍然比大多数串行化解决方案更快。这可能是对象记录数组最快的比较方法。