我想确定一个数组是否至少有一个元素也包含在另一个数组中。
为了即时:
arr0 = [0]
arr1 = [1,2,3]
arr2 = [2,3,4]
arr3 = [1,5,3]
arrCompare(arr0, arr1) // false
arrCompare(arr1, arr2) // true
arrCompare(arr1, arr3) // true
到目前为止,我有:
array_has_one_common_element = (a, b) ->
breakLoop1 = false
for num1 in a
for num2 in b
if num2 is num1
breakLoop1 = true; break
break if breakLoop1
return breakLoop1
因为这个函数将在服务器端使用nodejs并且可能必须处理大数组,所以我想知道如何将它重写为异步(使用异步库)。或者它是否足够有效?
答案 0 :(得分:2)
阵列交叉是一个非常慢的操作。因此,如果您使用大型数组,那么最好使用hashsets。
这是我使用hashsets的交集实现:
hashset = (elements) ->
return elements unless Array.isArray elements
set = {}
set[e] = true for e in elements
set
intersect = (a, b) ->
s1 = hashset a
s2 = hashset b
s3 = {}
for k of s1
s3[k] = true if s2[k]
s3
arrCompare = (a, b) ->
Object.keys(intersect a, b).length isnt 0
我认为你实际上并不需要异步。如果您不希望数组操作阻止主线程 - 将它们分派给另一个进程(worker)。
以下是benchmark.js的基准测试:
arr1 = [1..9999];
arr2 = [9999..99999];
{ name: 'My Code',
mean: 0.004182571958225297 }
{ name: 'Your Code',
mean: 2.1228081478333336 }
{ name: 'askkirati\'s Synchronous Code',
mean: 3.569238156 }
两个字符串数组的相同基准:
arr1 = (Math.random().toString(36).slice(2,12) for i in [1..9999])
arr2 = (Math.random().toString(36).slice(2,12) for i in [1..9999])
{ name: 'My Code',
mean: 0.009257149728395064 }
{ name: 'Your Code',
mean: 1.5913590743333332 }
{ name: 'askkirati\'s Synchronous Code',
mean: 1.418200398 }
我还尝试了两个非常庞大的数组,但我放弃了等待所有方法的完成:
arr1 = [1..999999]
arr2 = [999999..9999999]
{ name: 'My Code',
mean: 1.6512419735000001 }
如您所见,hashmap交集比循环交叉更快。在我的电脑上只需1.6秒即可与两个999999元素阵列相交。
答案 1 :(得分:1)
这是使用async.some
的一种方法var async = require('async');
var arr0 = [0];
var arr1 = [1,2,3];
var arr2 = [2,3,4];
var arr3 = [1,5,3];
function testExist(arrayToCheck, arrayInCheck, mainCallback){
async.some(arrayToCheck, function(item, callback){
if(arrayInCheck.indexOf(item) != -1){
callback(true);
}
else{
callback(false);
}
}, function(result){
mainCallback(result);
});
}
testExist(arr0, arr1, function(result){
console.log(result);
});
testExist(arr1, arr2, function(result){
console.log(result);
});
testExist(arr2, arr3, function(result){
console.log(result);
});
以下是不使用异步库的示例,Node.js支持array.some
var arr0 = [0];
var arr1 = [1,2,3];
var arr2 = [2,3,4];
var arr3 = [1,5,3];
function testWithoutAsyncLibExist(arrayToCheck, arrayInCheck, callback){
var check = arrayToCheck.some(function(el, index, array){
return (arrayInCheck.indexOf(el) != -1);
});
callback(check);
}
testWithoutAsyncLibExist(arr0, arr1, function(result){
console.log(result);
});
testWithoutAsyncLibExist(arr1, arr2, function(result){
console.log(result);
});
testWithoutAsyncLibExist(arr2, arr3, function(result){
console.log(result);
});