javascript 如何比较javascript数组的内容,而不是它们的顺序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29672847/
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 compare contents of javascript array, but not the order of them?
提问by kramer65
As the title says I want to compare two js arrays in which I only care about the contents being the same, but I don't care about the order of them being the same. So what I would expect is this:
正如标题所说,我想比较两个 js 数组,其中我只关心内容是否相同,但我不关心它们的顺序是否相同。所以我期望的是:
[1, 2, 3, 3] == [1, 2, 3, 3] // True
[1, 2, 3, 3] == [1, 3, 2, 3] // True
[1, 2, 3, 3] == [1, 2] // False
[1, 2, 3, 3] == [1, 2, 3] // False
[1, 2, 3, 3] == [1, 2, 3, 3, 3] // False
[1, 2, 3, 3] == [1, "2, 3, 3"] // False
Obviously the comparison operator doesn't work. From this SO answerI got the Array.prototype method below, but that unfortunately also checks if the order is the same.
显然比较运算符不起作用。从这个 SO answer我得到了下面的 Array.prototype 方法,但不幸的是,它也会检查顺序是否相同。
So does anybody know how I can check if two js arrays contain the same elements, not taking into account the order of the elements? All tips are welcome!
那么有人知道如何检查两个 js 数组是否包含相同的元素,而不考虑元素的顺序吗?欢迎所有提示!
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;
// compare lengths - can save a lot of time
if (this.length != array.length)
return false;
for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
回答by Omar Elawady
sort them before comparing:
在比较之前对它们进行排序:
from the comment below, if you want the 2 arrs to contain different primitive type.add this sort function.
从下面的评论中,如果您希望 2 个 arrs 包含不同的原始类型,请添加此排序功能。
function s(x,y){
var pre = ['string' , 'number' , 'bool']
if(typeof x!== typeof y )return pre.indexOf(typeof y) - pre.indexOf(typeof x);
if(x === y)return 0;
else return (x > y)?1:-1;
}
var arr1 = [1, 2, 3, 3].sort(s);
var arr2 = [1, 3, 2, 3].sort(s);
arr1.equals(arr2);// true
回答by Felix Kling
Here is a solution that works for primitive values. It uses an object as a primitive map and counts the number of occurrences of each value. However, it also considers the data type of each value.
这是一个适用于原始值的解决方案。它使用一个对象作为原始映射并计算每个值的出现次数。但是,它还考虑了每个值的数据类型。
It checks the length of the arrays first, as shortcut:
它首先检查数组的长度,作为快捷方式:
function equals(a, b) {
if (a.length !== b.length) {
return false;
}
var seen = {};
a.forEach(function(v) {
var key = (typeof v) + v;
if (!seen[key]) {
seen[key] = 0;
}
seen[key] += 1;
});
return b.every(function(v) {
var key = (typeof v) + v;
if (seen[key]) {
seen[key] -= 1;
return true;
}
// not (anymore) in the map? Wrong count, we can stop here
});
}