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

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


当前回答

不清楚你所说的“相同”是什么意思。例如,下面的数组a和b是否相同(请注意嵌套数组)?

var a = ["foo", ["bar"]], b = ["foo", ["bar"]];

这里有一个优化的数组比较函数,它使用严格的相等性依次比较每个数组的对应元素,并且不递归比较本身为数组的数组元素,这意味着对于上面的示例,arraysIncore(a,b)将返回false。它适用于一般情况,而基于JSON和join()的解决方案不会:

function arraysIdentical(a, b) {
    var i = a.length;
    if (i != b.length) return false;
    while (i--) {
        if (a[i] !== b[i]) return false;
    }
    return true;
};

其他回答

与JSON.encode相同的行是使用join()。

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    //slice so we do not effect the original
    //sort makes sure they are in order
    //join makes it a string so we can do a string compare
    var cA = arrA.slice().sort().join(","); 
    var cB = arrB.slice().sort().join(",");

    return cA===cB;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];  //will return true

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //true

唯一的问题是,如果您关心上次比较测试的类型。如果你关心类型,你将不得不循环。

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;

    //slice so we do not effect the orginal
    //sort makes sure they are in order
    var cA = arrA.slice().sort(); 
    var cB = arrB.slice().sort();

    for(var i=0;i<cA.length;i++){
         if(cA[i]!==cB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,b) );  //true
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false

如果顺序应该保持不变,而不是循环,则不需要排序。

function checkArrays( arrA, arrB ){

    //check if lengths are different
    if(arrA.length !== arrB.length) return false;


    for(var i=0;i<arrA.length;i++){
         if(arrA[i]!==arrB[i]) return false;
    }

    return true;

}

var a = [1,2,3,4,5];
var b = [5,4,3,2,1];
var c = [1,2,3,4];
var d = [1,2,3,4,6];
var e = ["1","2","3","4","5"];

console.log( checkArrays(a,a) );  //true
console.log( checkArrays(a,b) );  //false
console.log( checkArrays(a,c) );  //false
console.log( checkArrays(a,d) );  //false
console.log( checkArrays(a,e) );  //false

我的解决方案比较对象,而不是数组。这将以与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;
}
In a simple way uning stringify but at same time thinking in complex arrays:

**Simple arrays**:  
var a = [1,2,3,4];  
var b = [4,2,1,4];  
JSON.stringify(a.sort()) === JSON.stringify(b.sort()) // true  

**Complex arrays**:  
var a = [{id:5,name:'as'},{id:2,name:'bes'}];  
var b = [{id:2,name:'bes'},{id:5,name:'as'}];  
JSON.stringify(a.sort(function(a,b) {return a.id - b.id})) === JSON.stringify(b.sort(function(a,b) {return a.id - b.id})) // true  

**Or we can create a sort function**  

function sortX(a,b) {  
return a.id -b.id; //change for the necessary rules  
}  
JSON.stringify(a.sort(sortX)) === JSON.stringify(b.sort(sortX)) // true  

一种简单的方法:

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

这是一个字体版本:

//https://stackoverflow.com/a/16436975/2589276
export function arraysEqual<T>(a: Array<T>, b: Array<T>): boolean {
    if (a === b) return true
    if (a == null || b == null) return false
    if (a.length != b.length) return false

    for (var i = 0; i < a.length; ++i) {
        if (a[i] !== b[i]) return false
    }
    return true
}

//https://stackoverflow.com/a/16436975/2589276
export function arraysDeepEqual<T>(a: Array<T>, b: Array<T>): boolean {
    return JSON.stringify(a) === JSON.stringify(b)
}

摩卡的一些测试用例:

it('arraysEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']

    expect(arraysEqual(a, b)).to.equal(true)
    expect(arraysEqual(c, d)).to.equal(true)
    expect(arraysEqual(a, d)).to.equal(false)
    expect(arraysEqual(e, f)).to.equal(true)
    expect(arraysEqual(f, g)).to.equal(false)
})

it('arraysDeepEqual', function () {
    let a = [1,2]
    let b = [1,2]
    let c = [2,3]
    let d = [2, 3]
    let e = ['car','apple','banana']
    let f = ['car','apple','banana']
    let g = ['car','apple','banan8']
    let h = [[1,2],'apple','banan8']
    let i = [[1,2],'apple','banan8']
    let j = [[1,3],'apple','banan8']

    expect(arraysDeepEqual(a, b)).to.equal(true)
    expect(arraysDeepEqual(c, d)).to.equal(true)
    expect(arraysDeepEqual(a, d)).to.equal(false)
    expect(arraysDeepEqual(e, f)).to.equal(true)
    expect(arraysDeepEqual(f, g)).to.equal(false)
    expect(arraysDeepEqual(h, i)).to.equal(true)
    expect(arraysDeepEqual(h, j)).to.equal(false)
})