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

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


当前回答

选择是否比较订单:

function arraysEqual(a1, a2, compareOrder) {
    if (a1.length !== a2.length) {
        return false;
    }

    return a1.every(function(value, index) {
        if (compareOrder) {
            return value === a2[index];
        } else {
            return a2.indexOf(value) > -1;
        }
    });
}

其他回答

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

以下是我的解决方案:

/**
 * 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坏了;)

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

我的解决方案比较对象,而不是数组。这将以与Tomáš相同的方式工作,因为数组是对象,但没有警告:

Object.prototype.compare_to = function(comparable){
    
    // Is the value being compared an object
    if(comparable instanceof Object){
        
        // Count the amount of properties in @comparable
        var count_of_comparable = 0;
        for(p in comparable) count_of_comparable++;
        
        // Loop through all the properties in @this
        for(property in this){
            
            // Decrements once for every property in @this
            count_of_comparable--;
            
            // Prevents an infinite loop
            if(property != "compare_to"){
                
                // Is the property in @comparable
                if(property in comparable){
                    
                    // Is the property also an Object
                    if(this[property] instanceof Object){
                        
                        // Compare the properties if yes
                        if(!(this[property].compare_to(comparable[property]))){
                            
                            // Return false if the Object properties don't match
                            return false;
                        }
                    // Are the values unequal
                    } else if(this[property] !== comparable[property]){
                        
                        // Return false if they are unequal
                        return false;
                    }
                } else {
                
                    // Return false if the property is not in the object being compared
                    return false;
                }
            }
        }
    } else {
        
        // Return false if the value is anything other than an object
        return false;
    }
    
    // Return true if their are as many properties in the comparable object as @this
    return count_of_comparable == 0;
}

我喜欢将Undercore库用于数组/对象密集型编码项目。。。在Undercore和Lodash中,无论您是比较数组还是对象,它看起来都是这样的:

_.isEqual(array1, array2)   // returns a boolean
_.isEqual(object1, object2) // returns a boolean

Undercore is Equal文档Lodash isEqual文档

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

import isEqual from "lodash/isEqual";

const isTwoArraysEqual = isEqual(array1, array2);