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

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


当前回答

这里有一个CoffeeScript版本,适合那些喜欢它的人:

Array.prototype.equals = (array) ->
  return false if not array # if the other array is a falsy value, return
  return false if @length isnt array.length # compare lengths - can save a lot of time

  for item, index in @
    if item instanceof Array and array[index] instanceof Array # Check if we have nested arrays
      if not item.equals(array[index]) # recurse into the nested arrays
        return false
    else if this[index] != array[index]
      return false # Warning - two different object instances will never be equal: {x:20} != {x:20}
  true

所有学分都归@tomas zato所有。

其他回答

虽然这只适用于标量数组(请参见下面的注释),但代码很短:

array1.length === array2.length && array1.every(function(value, index) { return value === array2[index]})

与上文相同,但在ECMAScript 6/CoffeeScript/TypeScript中使用箭头函数:

array1.length === array2.length && array1.every((value, index) => value === array2[index])

(注意:这里的“scalar”表示可以使用==直接比较的值。因此:数字、字符串、引用对象、引用函数。有关比较运算符的更多信息,请参阅MDN引用)。

更新

根据我在评论中看到的内容,对数组进行排序和比较可能会得到准确的结果:

const array2Sorted = array2.slice().sort();
array1.length === array2.length && array1.slice().sort().every(function(value, index) {
    return value === array2Sorted[index];
});

Eg:

array1 = [2,3,1,4];
array2 = [1,2,3,4];

然后上述代码将返回true

我相信简单的JS和ECMAScript 2015,这很好理解。

var is_arrays_compare_similar = function (array1, array2) {

    let flag = true;

    if (array1.length == array2.length) {

        // check first array1 object is available in array2 index
        array1.every( array_obj => {
            if (flag) {
                if (!array2.includes(array_obj)) {
                    flag = false;
                }
            }
        });
        
        // then vice versa check array2 object is available in array1 index
        array2.every( array_obj => {
            if (flag) {
                if (!array1.includes(array_obj)) {
                    flag = false;
                }
            }
        });

        return flag;
    } else {
        return false;
    }
    
}

所有其他解决方案看起来都很复杂。这可能不是处理所有边缘情况的最有效方法,但它对我来说非常有用。

Array.prototype.includesArray = function(arr) {
  return this.map(i => JSON.stringify(i)).includes(JSON.stringify(arr))
}

用法

[[1,1]].includesArray([1,1])
// true

[[1,1]].includesArray([1,1,2])
// false

这个方法只适用于标量数组,就像这个问题的第二个投票答案一样。

变量arrs=[[[1,2,3],[1,2,3]],//真[[1,2,3,4],[1,2,3],//错误[[1,2,3],[1,2,3,4]],//错误]常量数组相等=(一,二)=>(一个滤波器((i,n)=>两个[n]==i)。长度==一个长度)&&(两个滤波器(i,n)=>一个[n]==i)。长==两个长度)arrs.forEach(arr=>{console.log(arraysEqual(arr[0],arr[1]))})

没有ES6语法:

变量arrs=[[[1,2,3],[1,2,3]],//真[[1,2,3,4],[1,2,3],//错误[[1,2,3],[1,2,3,4]],//错误]函数arraysEqual(一,二){return(one.filter((i,n)=>two[n]==i).length==one.length)&&(two.filter}arrs.forEach(arr=>{console.log(arraysEqual(arr[0],arr[1]))})

在我的例子中,比较数组只包含数字和字符串。此函数将显示数组是否包含相同的元素。

function are_arrs_match(arr1, arr2){
    return arr1.sort().toString() === arr2.sort().toString()
}

让我们测试一下!

arr1 = [1, 2, 3, 'nik']
arr2 = ['nik', 3, 1, 2]
arr3 = [1, 2, 5]

console.log (are_arrs_match(arr1, arr2)) //true
console.log (are_arrs_match(arr1, arr3)) //false