2012-09-15 53 views
20

我有兩個數組,我希望能夠比較兩個,只返回匹配的值。例如兩個數組的值都是cat,這樣就會返回。我還沒有找到像這樣的東西。什麼是最好的方式來回報相似之處?如何找到兩個數組中的匹配值?

var array1 = ["cat", "sum","fun", "run"]; 
var array2 = ["bat", "cat","dog","sun", "hut", "gut"]; 

if array1 value is equal to array2 value then return match: cat 
+0

類似於http:// stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript –

回答

31

當然,我的做法是,通過第一陣列循環一旦檢查索引第二個數組中的每個值。如果索引是> -1,那麼push它將返回到返回的數組上。

​Array.prototype.diff = function(arr2) { 
    var ret = []; 
    for(var i in this) { 
     if(arr2.indexOf(this[i]) > -1){ 
      ret.push(this[i]); 
     } 
    } 
    return ret; 
}; 

我的解決方案不使用兩個循環像其他人,因此它可能跑快一點。如果你想避免使用for..in,你既可以陣列第一排序重新索引所有的價值:

Array.prototype.diff = function(arr2) { 
    var ret = []; 
    this.sort(); 
    arr2.sort(); 
    for(var i = 0; i < this.length; i += 1) { 
     if(arr2.indexOf(this[i]) > -1){ 
      ret.push(this[i]); 
     } 
    } 
    return ret; 
}; 

使用看起來像:

var array1 = ["cat", "sum","fun", "run", "hut"]; 
var array2 = ["bat", "cat","dog","sun", "hut", "gut"]; 

console.log(array1.diff(array2)); 

如果你有一個問題/問題擴展陣列原型,你可以很容易地將其改變爲一個函數。

var diff = function(arr, arr2) { 

而且其中FUNC原本說thisarr2你會隨時隨地改變。

+1

'.indexOf()'只是移動循環。該方法在內部循環目標數組。 (https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf) –

+0

'.indexOf()'函數可能比循環遍歷整個數組更快,就像在兼容性中完成的那樣替代。 – jeremy

+0

indexOf()足夠聰明,可以在排序之後使用二進制搜索嗎?否則,這是O(N^2),因爲您實際上在執行嵌套循環,因爲indexOf()會執行線性掃描。即使沒有這個問題,爲什麼會產生linearithmic排序成本,當你可以在一個線性時間使用一個對象作爲散列表來做到這一點? – ChaseMedallion

1

完成的答案,所以我可以做格式化......

這就是你需要經歷的過程。循環訪問數組以獲取具體信息。

create an empty array 
loop through array1, element by element. { 
    loop through array2, element by element { 
    if array1.element == array2.element { 
     add to your new array 
    } 
    } 
} 
+0

這使用t他**數組1的長度*數組2的長度**數量的循環...在這種情況下24循環..它會更好,只是檢查array1中的值索引是否存在於array2然後只會使用1個循環。看到我的答案。 – jeremy

+0

我想過這個。 '.indexOf()'仍然不受支持,儘管它可以很容易地被monkeypatched ...和'.indexOf()',至少在Mozilla monkeypatch版本中(https://developer.mozilla.org/ en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf)仍然循環。它只是將其中一個循環移至'indexOf'函數。 –

+0

它在所有主流瀏覽器中都支持,請查看兼容性表... – jeremy

7

每次迭代第一陣列中的元素,然後檢查比賽時間循環通過第二陣列。

var array1 = ["cat", "sum", "fun", "run"], 
    array2 = ["bat", "cat", "dog", "sun", "hut", "gut"]; 

function getMatch(a, b) { 
    var matches = []; 

    for (var i = 0; i < a.length; i++) { 
     for (var e = 0; e < b.length; e++) { 
      if (a[i] === b[e]) matches.push(a[i]); 
     } 
    } 
    return matches; 
} 

getMatch(array1, array2); // ["cat"] 
+0

這使用**數組1的長度*數組2的長度**循環量...在這種情況下24循環。 – jeremy

+0

糟糕。感謝指出:) – 0x499602D2

+0

沒問題。它有效,但它非常不必要,可能會永遠運行。你可以查看我的答案可能是更好的1循環解決方案 – jeremy

0

如果值非空字符串或數字,你可以使用一個對象作爲字典:

var map = {}, result = [], i; 
for (i = 0; i < array1.length; ++i) { 
    map[array1[i]] = 1; 
} 

for (i = 0; i < array2.length; ++i) { 
    if (map[array2[i]] === 1) { 
     result.push(array2[i]); 

     // avoid returning a value twice if it appears twice in array 2 
     map[array2[i]] = 0; 
    } 
} 

return result; 
+0

使用2個循環。比其他解決方案更好,但你可以把它降到1 – jeremy

9

此函數在O(n log(n) + m log(m))中運行,與O(n*m)相比(如其他帶有迴路/ indexOf的解決方案中所示),如果您處理大量值,則該函數可能很有用。

但是,因爲既不是"a" > 1也不是"a" < 1,這隻適用於相同類型的元素。

function intersect_arrays(a, b) { 
    var sorted_a = a.concat().sort(); 
    var sorted_b = b.concat().sort(); 
    var common = []; 
    var a_i = 0; 
    var b_i = 0; 

    while (a_i < a.length 
      && b_i < b.length) 
    { 
     if (sorted_a[a_i] === sorted_b[b_i]) { 
      common.push(sorted_a[a_i]); 
      a_i++; 
      b_i++; 
     } 
     else if(sorted_a[a_i] < sorted_b[b_i]) { 
      a_i++; 
     } 
     else { 
      b_i++; 
     } 
    } 
    return common; 
} 

實施例:

var array1 = ["cat", "sum", "fun", "hut"], //modified for additional match 
    array2 = ["bat", "cat", "dog", "sun", "hut", "gut"]; 
intersect_arrays(array1, array2); 
>> ["cat", "hut"] 
+0

複雜性實際上是O(nlogn + mlogm + n + m),你計算時忘了考慮while循環。 – Partha

+0

@Partha'n'包含在越來越快的'n logn'中,這同樣適用於'm'和'm log n'。 – phant0m

1
use lodash 
GLOBAL.utils = require('lodash') 
var arr1 = ['first' , 'second']; 
var arr2 = ['second ']; 

var result = utils.difference (arr1 , arr2); 
    console.log ("result :" + result); 
2

正如@hanu提到的,你可以使用lodash但你也可以使用原生的JavaScript用:

const intersection = array1.filter(element => array2.includes(element)); 
0

我發現了什麼@ jota3提示完全爲我工作有輕微的改變。

var intersections = array1.filter(e => array2.indexOf(e) !== -1); 

希望這有助於!

0

隨着一些ES6:

let sortedArray = []; 
firstArr.map((first) => { 
    sortedArray[defaultArray.findIndex(def => def === first)] = first; 
}); 
sortedArray = sortedArray.filter(v => v); 

這個片段也是排序firstArr基礎的秩序的defaultArray

,如:

let firstArr = ['apple', 'kiwi', 'banana']; 
let defaultArray = ['kiwi', 'apple', 'pear']; 
... 
console.log(sortedArray); 
// ['kiwi', 'apple']; 
相關問題