2012-09-15 52 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']; 
相关问题