我正在学习Javascript,我在SO上看到了一个函数,用于比较数组以检查它们是否相同。但是,如果两个数组是[string1,string2]& [字符串2,字符串1]。基本上,这两个职位互换。代码如下:
function _compareArrays(arr1,arr2){
var result = arr1 != null && arr2 != null && arr1.length == arr2.length && arr1.every(function(element) {
return arr2.indexOf(element);
});
return result ;
}
但是,我希望这两个数组返回相同。所以,我将.every
更改为.indexOf()
,它似乎有效。但是,我有一个疑问,计数器究竟是如何增加的,以确保对每个元素进行比较?
我的意思是,就像在C ++中一样,我们这样做,
for (int i = 0; i < 10; i++)
if (arr1[i] == arr2[i]
cout<<"Elements are same\n";
在这里,我有一个明确的i++
,它会递增计数器。如何在上述功能中发生?
谢谢!
答案 0 :(得分:2)
将数组转换为对象。将数组值转换为键及其各自的计数值作为其值。当你只遍历数组一次时,这会更高效。
function compare(a, b) {
if (a.length !== b.length) {
return false;
}
let set = {};
a.forEach((i) => {
if (set[i] !== undefined) {
set[i]++;
} else {
set[i] = 1;
}
});
let difference = b.every((i) => {
if (set[i] === undefined) {
return false;
} else {
set[i]--;
if (set[i] === 0) {
delete set[i];
}
return true;
}
});
return Object.keys(set) == 0 && difference;
}
第一个数组上的第一个循环初始化set(对象),第二个数组上的第二个循环减去计数,并在计数达到0时删除键。如果找不到键或者该组没有在程序结束时为空,那么数组就不相似了。
答案 1 :(得分:1)
您目前遇到以下问题:
这两个数组会返回true
(我希望您明白这不是特定于这两个数组):[1, 2, 2]
,[1,1,2]
。这个问题是我在下面的解决方案中匹配后将索引设置为undefined
的原因。
indexOf
为无法找到的元素返回-1
,如果可以找到该元素,则返回任意数字>= 0
,-1
是真实的,所以如果一个元素无法找到,您的比较将返回true
,而0
是假的,因此如果元素位于第二个数组的第一个索引中,您的方法将返回false
(这意味着由于false
...),整个事情将成为every
。因此,您应该在~
调用结果indexOf
之前添加~arr2.indexOf(element)
。
参见this
Bitwise Not运算符(~
)上的MDN页面以及它如何解决
我提到的indexOf
问题。
我还建议您查看我的this回答关于truthy / falsy值以及它们与&&
和||
的互动方式。
所以试试这个(这主要是你的例子,除了没有indexOf
使用,我已经修复了问题#2):
function _compareArrays(arr1,arr2){
if(!(arr1 != null && arr2 != null && arr1.length == arr2.length)) {
return false;
}
/* copy the arrays so that the original arrays are not affected when we set the indices to "undefined" */
arr1 = [].concat(arr1);
arr2 = [].concat(arr2);
return arr1.every(function(element, index) {
return arr2.some(function(e, i) {
return e === element && (arr2[i] = undefined, true);
});
});
}
var x = ["str", "boo", "str"];
var y = ["boo", "str", "str"];
var z = ["abc", "def", "ghi"]
console.log(_compareArrays(x, y));
console.log(_compareArrays(x, z));
console.log(_compareArrays(z, z));
如果数组中有任何undefined
个元素,它将无效。
答案 2 :(得分:0)
所以最快的方法是对两个数组进行排序,然后逐个元素比较每个元素。这需要2n * log(n) + n
时间,而不是n 2 时间。
function compareArrays(arr1, arr2){
if(arr1.length !== arr2.length) return false;
// implement custom sort if necessary
arr1.sort();
arr2.sort();
// use normal for loop so we can return immediately if not equal
for(let i=0; i<arr1.length; i++){
if(arr1[i] !== arr2[i]) return false;
}
return true;
}