var a = [1, 2, 3];
var b = [3, 2, 1];
var c = new Array(1, 2, 3);

alert(a == b + "|" + b == c);

demo

如何检查这些数组是否相等,并获得一个方法,如果它们相等,则返回true ?

jQuery是否为此提供了任何方法?


当前回答

如果您希望检查对象数组的相等性和顺序并不重要,即。

areEqual ([{id:“0”},{id: " 1 "}], [{id: " 1 "}, {id: " 0 "})) / /真实的

首先要对数组进行排序。lodash有你需要的所有工具,通过组合sortBy和isEqual:

// arr1 & arr2: Arrays of objects 
// sortProperty: the property of the object with which you want to sort
// Note: ensure every object in both arrays has your chosen sortProperty
// For example, arr1 = [{id: "v-test_id0"}, {id: "v-test_id1"}]
// and          arr2 = [{id: "v-test_id1"}, {id: "v-test_id0"}]
// sortProperty should be 'id'

function areEqual (arr1, arr2, sortProperty) {
  return _.areEqual(_.sortBy(arr1, sortProperty), _.sortBy(arr2, sortProperty))
}

编辑:由于sortBy返回一个新数组,在排序之前不需要克隆数组。原始数组不会被改变。

注意,对于lodash的isEqual,顺序很重要。如果sortBy没有首先应用于每个数组,上面的例子将返回false。

其他回答

如果您正在使用lodash,并且不想修改任何一个数组,则可以使用_.xor()函数。它将两个数组作为集合进行比较,并返回包含它们之差的集合。如果此差值的长度为零,则两个数组本质上相等:

var a = [1, 2, 3];
var b = [3, 2, 1];
var c = new Array(1, 2, 3);
_.xor(a, b).length === 0
true
_.xor(b, c).length === 0
true

要做到这一点并不容易。我也需要这个,但我想要一个函数,可以接受任何两个变量,并测试是否相等。这包括非对象值、对象、数组和任何级别的嵌套。

在您的问题中,您提到希望忽略数组中值的顺序。我的解决方案本身并没有这样做,但您可以通过在比较是否相等之前对数组进行排序来实现

我还想将非对象转换为字符串,这样[1,2]===["1",2]

由于我的项目使用了UnderscoreJs,所以我决定将其作为一个mixin,而不是一个独立的函数。

您可以在http://jsfiddle.net/nemesarial/T44W4/上进行测试

这是我的mxin:

_.mixin({
  /**
  Tests for the equality of two variables
    valA: first variable
    valB: second variable
    stringifyStatics: cast non-objects to string so that "1"===1
  **/
  equal:function(valA,valB,stringifyStatics){
    stringifyStatics=!!stringifyStatics;

    //check for same type
    if(typeof(valA)!==typeof(valB)){
      if((_.isObject(valA) || _.isObject(valB))){
        return false;
      }
    }

    //test non-objects for equality
    if(!_.isObject(valA)){
      if(stringifyStatics){
        var valAs=''+valA;
        var valBs=''+valB;
        ret=(''+valA)===(''+valB);
      }else{
        ret=valA===valB;
      }
      return ret;
    }

    //test for length
    if(_.size(valA)!=_.size(valB)){
      return false;
    }

    //test for arrays first
    var isArr=_.isArray(valA);

    //test whether both are array or both object
    if(isArr!==_.isArray(valB)){
      return false;
    }

    var ret=true;
    if(isArr){
      //do test for arrays
      _.each(valA,function(val,idx,lst){
        if(!ret){return;}
        ret=ret && _.equal(val,valB[idx],stringifyStatics);
      });
    }else{
      //do test for objects
      _.each(valA,function(val,idx,lst){
        if(!ret){return;}

        //test for object member exists
        if(!_.has(valB,idx)){
          ret=false;
          return;
        }

        // test for member equality
        ret=ret && _.equal(val,valB[idx],stringifyStatics);
      });

    }
    return ret;
  }
});

下面是它的用法:

_.equal([1,2,3],[1,2,"3"],true)

要演示嵌套,你可以这样做:

_.equal(
    ['a',{b:'b',c:[{'someId':1},2]},[1,2,3]],
    ['a',{b:'b',c:[{'someId':"1"},2]},["1",'2',3]]
,true);

根据Tim James的回答和Fox32的评论,下面应该检查空值,假设两个空值不相等。

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); }

> arrays_equal([1,2,3], [1,3,4])
false
> arrays_equal([1,2,3], [1,2,3])
true
> arrays_equal([1,3,4], [1,2,3])
false
> arrays_equal(null, [1,2,3])
false
> arrays_equal(null, null)
false

这种方法很糟糕,但我把它留在这里作为参考,所以其他人会避免这种方法:


使用@ninjagecko的选项1最适合我:

Array.prototype.equals = function(array) {
    return array instanceof Array && JSON.stringify(this) === JSON.stringify(array) ;
}

a = [1, [2, 3]]
a.equals([[1, 2], 3]) // false
a.equals([1, [2, 3]]) // true

它还将处理null和未定义的情况,因为我们将它添加到数组的原型中,并检查另一个参数是否也是一个数组。

对于数字和字符串等原始值,这是一个简单的解决方案:

a = [1,2,3]

b = [3,2,1]

a.sort().toString() == b.sort().toString() 

调用sort()将确保元素的顺序无关紧要。toString()调用将创建一个值以逗号分隔的字符串,以便可以测试两个字符串是否相等。