簡體   English   中英

JavaScript:性能改進以查找兩個數組中的公共元素

[英]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.indexOfArray.prototype.includesArray.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM