为什么你的代码不起作用
JavaScript 有原始数据类型和非原始数据类型。
对于原始数据类型,==
并===
检查是否在酒吧两边的东西具有相同的值。这就是为什么1 === 1
是真的。
对于非原始数据类型(如数组),==
并===
检查引用相等性。也就是说,它们检查arr1
和是否arr2
是同一个对象。在您的示例中,两个数组具有相同顺序的相同对象,但并不等效。
解决方案
两个数组arr1
andarr2
具有相同的成员当且仅当:
和
所以这可以解决问题(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 的第二个解决方案更接近您尝试执行的操作:
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]`
更新
请参阅@Redu 的评论——我的解决方案是针对sameMembers
,但您可能想到的是sameMembersInOrder
也称为deepEquals
。
更新 2
如果你不关心数组成员的顺序,ES2015+Set
可能是比Array
. 请参阅有关如何实现isSuperset
和difference
使用危险的猴子补丁的MDN 说明。
更新 3
如果顺序无关紧要,最好使用集合。但是如果你必须使用数组,这个解决方案比我之前给出的解决方案具有更好的时间复杂度:
function sameMembers(arr1, arr2) {
const set1 = new Set(arr1);
const set2 = new Set(arr2);
return arr1.every(item => set2.has(item)) &&
arr2.every(item => set1.has(item))
}