如何知道两个数组是否具有相同的值

我有这两个数组:一个充满来自ajax请求的信息,另一个存储用户点击的button。 我使用这个代码(我填写了样本编号):

var array1 = [2, 4]; var array2 = [4, 2]; //It cames from the user button clicks, so it might be disordered. array1.sort(); //Sorts both Ajax and user info. array2.sort(); if (array1==array2) { doSomething(); }else{ doAnotherThing(); } 

但是,即使两个数组是相同的,但名称不同,它总是会给出false 。 (我在Chrome的JS控制台中检查过)。 那么,有什么办法可以知道这两个数组是否包含相同的? 为什么这是false ? 我怎样才能知道第一个数组中的哪些值不在第二个?

 Array.prototype.compare = function(testArr) { if (this.length != testArr.length) return false; for (var i = 0; i < testArr.length; i++) { if (this[i].compare) { //To test values in nested arrays if (!this[i].compare(testArr[i])) return false; } else if (this[i] !== testArr[i]) return false; } return true; } var array1 = [2, 4]; var array2 = [4, 2]; if(array1.sort().compare(array2.sort())) { doSomething(); } else { doAnotherThing(); } 

也许?

如果您的数组项不是对象,例如,如果它们是数字或string,则可以比较它们的连接string,看它们是否以任何顺序具有相同的成员 –

 var array1= [10, 6, 19, 16, 14, 15, 2, 9, 5, 3, 4, 13, 8, 7, 1, 12, 18, 11, 20, 17]; var array2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17]; if(array1.sort().join(',')=== array2.sort().join(',')){ alert('same members'); } else alert('not a match'); 

如果只想检查两个数组是否具有相同的值(不pipe每个值的出现次数和次序如何),则可以使用lodash执行此操作 :

 _.isEmpty(_.xor(array1, array2)) 

简单,漂亮!

为什么你的代码不工作

JavaScript具有原始数据types和非原始数据types。

对于原始数据types, =====检查条形两边的东西是否具有相同的值。 这就是为什么1 === 1是真的。

对于像数组这样的非原始数据types, =====检查引用是否相等。 也就是说,他们检查arr1arr2是否是同一个对象。 在你的例子中,两个数组以相同的顺序具有相同的对象,但并不等同。

解决scheme

两个数组arr1arr2具有相同的成员当且仅当:

  • arr2中的所有内容都在arr1

  • arr1中的所有内容都在arr2

所以这会做的(ES2016):

 const containsAll = (arr1, arr2) => arr2.every(arr2Item => arr1.includes(arr2Item)) const sameMembers = (arr1, arr2) => containsAll(arr1, arr2) && containsAll(arr2, arr1); sameMembers(arr1, arr2); // `true` 

使用Underscore的第二个解决scheme更接近您正在尝试执行的操作:

 arr1.sort(); arr2.sort(); _.isEqual(arr1, arr2); // `true` 

它的工作原理是因为isEqual检查“深度平等”,这意味着它看起来不仅仅是引用相等并比较值。

解决您的第三个问题

你也问如何找出arr1中哪些东西不包含在arr2

这将做到这一点(ES2015):

 const arr1 = [1, 2, 3, 4]; const arr2 = [3, 2, 1]; arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]` 

你也可以使用Underscore的difference :方法:

 _.difference(arr1, arr2); // `[4]` 

UPDATE

请参阅sameMembers的评论 – 我的解决scheme是针对同一个sameMembers ,但您可能想到的是sameMembersInOrder也称为deepEquals

更新2

如果您不关心数组成员的顺序,ES2015 +的Set可能是比Array更好的数据结构。 请参阅MDN有关如何使用危险的猴子补丁实现isSupersetdifference注意事项 。

对象相等性检查: JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())

上面的testing也适用于对象数组,在这种情况下使用sorting函数,如http://www.w3schools.com/jsref/jsref_sort.asp

可能足够用扁平的JSON模式的小数组。

当你比较这两个数组时,你比较代表数组的对象,而不是内容。

你将不得不使用一个函数来比较两者。 你可以写你自己的,只是循环一个,并比较它与另一个检查后,长度是相同的。

如果你正在使用Prototype Framework,你可以使用数组的交集方法来找出它们是相同的(不pipe顺序如何):

 var array1 = [1,2]; var array2 = [2,1]; if(array1.intersect(array2).length === array1.length) { alert("arrays are the same!"); } 

我有一个游戏项目简单的整数值
每个数组中的值数量较less,也需要原始数组不变
所以,我做了下面,它工作正常。 (代码编辑粘贴在这里)

 var sourceArray = [1, 2, 3]; var targetArray = [3, 2, 1]; if (sourceArray.length !== targetArray.length) { // not equal // did something return false; } var newSortedSourceArray = sourceArray.slice().sort(); var newSortedTargetArray = targetArray.slice().sort(); if (newSortedSourceArray.toString() !== newSortedTargetArray.toString()) { // MAIN CHECK // not equal // did something return false; } else { // equal // did something // continued further below } // did some more work return true; 

希望有所帮助。

 var arraysEqual = function(_arr1, _arr2) { if (!Array.isArray(_arr1) || ! Array.isArray(_arr2) || _arr1.length !== _arr2.length) return false; var arr1 = _arr1.concat().sort(); var arr2 = _arr2.concat().sort(); for (var i = 0; i < arr1.length; i++) { if (arr1[i] !== arr2[i]) return false; } return true; } 

请注意,这不会像接受的答案那样修改原始数组。

请检查这个答案

 var arr1= [12,18]; var arr2= [12, 18, 20, 11, 19, 14, 6, 7, 8, 16, 9, 3, 1, 13, 5, 4, 15, 10, 2, 17]; for(i=0;i<arr1.length;i++) { var array1=arr1[i]; for(j=0;j<arr2.length;j++) { var array2=arr2[j]; if(array1==array2) { return true; } } }