2013-12-10 63 views
0

我想確定一個數組是否至少有一個元素也包含在另一個數組中。檢查數組中是否至少有一個元素也是另一個數組元素的有效異步方法

對於instantce:

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服務器端來使用,並且必須處理的大陣,我是想知道如何將其重寫爲異步(使用異步庫)。或者它是否足夠有效?

+1

是否可以將數組轉換成HashSets(地圖)並將它們相交?如果交集爲空 - 數組沒有公共項目,否則交集是常用項目。當交點爲O(n)時,組合循環爲O(n^2) –

回答

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交集的工作速度比環路交集快得多。我的PC上只需要1.6秒就可以將兩個999999元素數組相交。

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); 
}); 
相關問題