Javascript 如何知道两个数组是否具有相同的值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6229197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to know if two arrays have the same values
提问by Carlos Precioso
I have these two arrays: one is filled with information from an ajax request and another stores the buttons the user clicks on. I use this code (I filled with sample numbers):
我有这两个数组:一个填充来自 ajax 请求的信息,另一个存储用户点击的按钮。我使用此代码(我填充了示例编号):
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();
}
But it always gives false
, even if the two arrays are the same, but with different name. (I checked this in Chrome's JS Console). So, is there any way I could know if these two arrays contain the same? Why is it giving false
? How can I know which values in the first array are not in the second?
但它总是给出false
,即使两个数组相同,但名称不同。(我在 Chrome 的 JS 控制台中检查了这个)。那么,有什么办法可以知道这两个数组是否包含相同的内容?为什么要给予false
?我怎么知道第一个数组中的哪些值不在第二个数组中?
采纳答案by Maciej Krawczyk
function arraysEqual(_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;
}
Note that this doesn't modify original arrays unlike a previous answer.
请注意,与之前的答案不同,这不会修改原始数组。
回答by kennebec
If your array items are not objects- if they are numbers or strings, for example, you can compare their joined strings to see if they have the same members in any order-
如果您的数组项不是对象-例如,如果它们是数字或字符串,您可以比较它们的连接字符串以查看它们是否按任何顺序具有相同的成员-
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');
回答by Technotronic
回答by isakkarlsson
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();
}
Maybe?
也许?
回答by Max Heiber
Why your code didn't work
为什么你的代码不起作用
JavaScript has primitive data typesand non-primitive data types.
JavaScript 有原始数据类型和非原始数据类型。
For primitive data types, ==
and ===
check whether the things on either side of the bars have the same value. That's why 1 === 1
is true.
对于原始数据类型,==
并===
检查是否在酒吧两边的东西具有相同的值。这就是为什么1 === 1
是真的。
For non-primitive data types like arrays, ==
and ===
check for reference equality. That is, they check whether arr1
and arr2
are the same object. In your example, the two arrays have the same objects in the same order, but are not equivalent.
对于非原始数据类型(如数组),==
并===
检查引用相等性。也就是说,它们检查arr1
和是否arr2
是同一个对象。在您的示例中,两个数组具有相同顺序的相同对象,但并不等效。
Solutions
解决方案
Two arrays, arr1
and arr2
, have the same members if and only if:
两个数组arr1
andarr2
具有相同的成员当且仅当:
- Everything in
arr2
is inarr1
- 一切都
arr2
在arr1
AND
和
- Everything in
arr1
is inarr2
- 一切都
arr1
在arr2
So this will do the trick (ES2016):
所以这可以解决问题(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`
This second solution using Underscoreis closer to what you were trying to do:
使用Underscore 的第二个解决方案更接近您尝试执行的操作:
arr1.sort();
arr2.sort();
_.isEqual(arr1, arr2); // `true`
It works because isEqual
checks for "deep equality," meaning it looks at more than just reference equality and compares values.
它之所以有效是因为isEqual
检查“深度相等”,这意味着它不仅仅查看引用相等和比较值。
A solution to your third question
解决你的第三个问题
You also asked how to find out which things in arr1
are not contained in arr2
.
你还问我如何找出哪些东西arr1
在不包含arr2
。
This will do it (ES2015):
这将做到(ES2015):
const arr1 = [1, 2, 3, 4];
const arr2 = [3, 2, 1];
arr1.filter(arr1Item => !arr2.includes(arr1Item)); // `[4]`
You could also use Underscore's difference
: method:
您还可以使用 Underscore 的difference
: 方法:
_.difference(arr1, arr2); // `[4]`
UPDATE
更新
See @Redu's comment—my solution is for sameMembers
, but what you may have in mind is sameMembersInOrder
also-known-as deepEquals
.
请参阅@Redu 的评论——我的解决方案是针对sameMembers
,但您可能想到的是sameMembersInOrder
也称为deepEquals
。
UPDATE 2
更新 2
If you don't care about the order of the members of the arrays, ES2015+'s Set
may be a better data structure than Array
. See the MDN notes on how to implement isSuperset
and difference
using dangerous monkey-patching.
如果你不关心数组成员的顺序,ES2015+Set
可能是比Array
. 请参阅有关如何实施isSuperset
和difference
使用危险的猴子补丁的MDN 说明。
回答by Sandeep
Object equality check:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())
对象相等性检查:JSON.stringify(array1.sort()) === JSON.stringify(array2.sort())
The above test also works with arrays of objects in which case use a sort function as documented in http://www.w3schools.com/jsref/jsref_sort.asp
上述测试也适用于对象数组,在这种情况下,请使用http://www.w3schools.com/jsref/jsref_sort.asp 中记录的排序函数
Might suffice for small arrays with flat JSON schemas.
对于具有扁平 JSON 模式的小型数组可能就足够了。
回答by canbax
Our aim is basically to check whether 2 arrays are equal sets. setis the mathematically defined set. Fastest sorting asymptotically takes O(nlog(n))time. So If you sort an array, it would take at least O(nlog(n))time. But you can do this task faster, which asymptotically takes O(n)time (average case not worst case) with a dictionary data structure. In JS, a dictionary is simply an object with keys and values.
我们的目标基本上是检查 2 个数组是否是相等的集合。set是数学定义的set。最快的排序渐近花费O(nlog(n))时间。因此,如果对数组进行排序,则至少需要O(nlog(n))时间。但是您可以更快地完成此任务,使用字典数据结构渐近地花费O(n)时间(平均情况不是最坏的情况)。在 JS 中,字典只是一个带有键和值的对象。
// assumes array elements are primitive types
function areArraysEqualSets(a1, a2) {
let superSet = {};
for (let i = 0; i < a1.length; i++) {
const e = a1[i] + typeof a1[i];
superSet[e] = 1;
}
for (let i = 0; i < a2.length; i++) {
const e = a2[i] + typeof a2[i];
if (!superSet[e]) {
return false;
}
superSet[e] = 2;
}
for (let e in superSet) {
if (superSet[e] === 1) {
return false;
}
}
return true;
}
Note that this function works with arrays of primitive types and assumes a1 and a2 are arrays.
请注意,此函数适用于原始类型的数组,并假定 a1 和 a2 是数组。
回答by Andrew
When you compare those two arrays, you're comparing the objects that represent the arrays, not the contents.
当您比较这两个数组时,您是在比较表示数组的对象,而不是内容。
You'll have to use a function to compare the two. You could write your own that simply loops though one and compares it to the other after you check that the lengths are the same.
您必须使用一个函数来比较两者。您可以编写自己的代码,在检查长度是否相同后,简单地循环一个循环并将其与另一个进行比较。
回答by camslice
Simple solution for shallow equality using ES6:
使用 ES6 实现浅等式的简单解决方案:
const arr1test = arr1.slice().sort()
const arr2test = arr2.slice().sort()
const equal = !arr1test.some((val, idx) => val !== arr2test[idx])
Creates shallow copies of each array and sorts them. Then uses some()
to loop through arr1test
values, checking each value against the value in arr2test
with the same index. If all values are equal, some()
returns false
, and in turn equal
evaluates to true
.
创建每个数组的浅拷贝并对其进行排序。然后使用some()
循环遍历arr1test
值,根据arr2test
具有相同索引的值检查每个值。如果所有值都相等,则some()
返回false
,然后equal
计算结果为true
。
Could also use every()
, but it would have to cycle through every element in the array to satisfy a true
result, whereas some()
will bail as soon as it finds a value that is not equal:
也可以使用every()
,但它必须循环遍历数组中的每个元素才能满足true
结果,而some()
一旦找到不相等的值就会退出:
const equal = arr1test.every((val, idx) => val === arr2test[idx])
回答by Ben Carp
Using ES6
使用 ES6
We'll use Ramda's equals
function, but instead we can use Lodash's or Underscore's isEqual
:
我们将使用 Ramda 的equals
函数,但我们可以使用 Lodash 或 Underscore 的函数isEqual
:
const R = require('ramda');
const arraysHaveSameValues = (arr1, arr2) => R.equals( [...arr1].sort(), [...arr2].sort() )
Using the spread opporator, we avoid mutating the original arrays, and we keep our function pure.
使用扩展运算符,我们避免改变原始数组,并保持我们的函数纯。