[英]JavaScript: performance improvement to find the common elements in two array
我有一個用於搜索兩個數組中最長公共元素的函數:
/**
* Return the common elements in two array
*/
function searchArrayInArray(array1, array2) {
var result = [];
for (var j = 0, e = array1.length; j < e; j++){
var element = array1[j];
if( array2.indexOf(element) !== -1 ){
result.push(element);
}
}
return result;
}
這種方法有效,但我想提高性能,因為我多次調用它。
是否有任何適用的性能改進?
旁注:數組中的元素是未排序的字符串
/** * Return the common elements in two array */ function searchArrayInArray(array1, array2) { var result = []; for (var j = 0, e = array1.length; j < e; j++){ var element = array1[j]; if( array2.indexOf(element) !== -1 ){ result.push(element); } } return result; } var result = searchArrayInArray(['a', 'b'], ['b', 'c']); document.getElementById("result").innerHTML = JSON.stringify(result, null, 2);
<pre id="result"></pre>
如果您關心性能,您將需要使用提供良好查找時間的數據結構。 Array.prototype.indexOf
、 Array.prototype.includes
和Array.prototype.find
等數組方法都有線性查找。 Map
具有二進制查找, Set
具有常量查找。 我認為Set
在這種情況下將是理想的。
intersection
的直接實現 -
const intersection = (a1 = [], a2 = []) => { const s = new Set(a1) const result = [] for (const x of a2) if (s.has(x)) result.push(x) return result } console.log(intersection(['a', 'b'], ['b', 'c'])) // [ 'b' ]
這可以使用像Array.prototype.filter
這樣的高階函數來簡化一點 -
const intersection = (a1 = [], a2 = []) => { const s = new Set(a1) return a2.filter(x => s.has(x)) } console.log(intersection(['a', 'b'], ['b', 'c'])) // [ 'b' ]
這個概念可以擴展到支持任意數量的數組相交 -
const intersection = (a1 = [], a2 = []) => { const s = new Set(a1) return a2.filter(x => s.has(x)) } const intersectAll = (a = [], ...more) => more.reduce(intersection, a) console.log(intersectAll(['a', 'b'], ['b', 'c'], ['b', 'd'], ['e', 'b'])) // [ 'b' ]
那么 indexOf() 是 O(n) 所以通過使用 Set() 你可以將復雜度從 O(n^2) 提高到 O(n * log n)
function searchArrayInArray(array1, array2) {
var result = [];
let set = new Set();
for(el of array2){
set.add(el);
}
for (var j = 0, e = array1.length; j < e; j++){
var element = array1[j];
if( set.has(element) ){
result.push(element);
}
}
return result;
}
最簡單的方法:
var a = [1,2,3,4,5,6,7,8,9,10];
var b = [2,4,5,7,11,15];
var c = a.filter(value => b.includes(value))
console.log(c)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.