2016-11-10 35 views
1

我有一個真正的大表現打_.uniqWith(newSelectedModelList, _.isEqual);lodash _.uniq與性能差距

我正在比較2100個元素的數組。每個元素有{ name: 'foo', year: '1993'},{ name: 'foo', year: '1993'},{ name: 'foo', year: '2000'}並刪除具有相同的nameyear的副本。

有沒有更快的方法來做到這一點?或者比lodash更好的工具?

+0

什麼是「性能打擊」被比較? – guest271314

+0

數組數據是否來自數據庫/服務器?刪除重複的服務器端可能要快得多。 –

+2

使用'function(obj){return obj.name +','+ obj.year}'作爲標準,嘗試https://lodash.com/docs/4.16.6#uniqBy。即使使用'function(foo){console.log(foo)}',它也會是'O(n)' –

回答

3

您可以使用ES6 filterSet。下面的函數傳遞一個Set作爲上下文(this)回調:

function uniques(arr) { 
 
    return arr.filter(function ({year, name}, key) { 
 
     return !this.has(key = year + name) && this.add(key); 
 
    }, new Set()); 
 
} 
 
// Sample data 
 
var newSelectedModelList = [ 
 
    { name: 'foo', year: '1993'}, 
 
    { name: 'foo', year: '1993'}, 
 
    { name: 'foo', year: '2000'} 
 
]; 
 
// Output result 
 
console.log(uniques(newSelectedModelList));

如果你想過濾在給定的變量發生,而不是通過返回一個新的數組的功能,我建議只是一句給定的陣列和重新填充它:它會更快更長的陣列,而不是拼接重複了,一個接一個:

function uniques(arr) { 
 
    var res = arr.filter(function ({year, name}, key) { 
 
     return !this.has(key = year + name) && this.add(key); 
 
    }, new Set()); 
 
    // replace content in arr: 
 
    arr.splice(0, arr.length, res); 
 
} 
 
// Sample data 
 
var newSelectedModelList = [ 
 
    { name: 'foo', year: '1993'}, 
 
    { name: 'foo', year: '1993'}, 
 
    { name: 'foo', year: '2000'} 
 
]; 
 
// replace in-place: 
 
uniques(newSelectedModelList); 
 
// Output result 
 
console.log(newSelectedModelList);

JS fiddle我發佈與解決方案,在guest271314 had posted我寫這篇文章時的性能比較。在我的電腦上,控制檯輸出報告了這些測量值:

number of original elements: 30000 
    solution count duration 
----------- ----- -------- 
    trincot 14456 00020.14 
guest271314 14456 00351.99 

count列給出了保留在最終結果中的唯一元素的數量。這個數字可以在不同的運行中改變,因爲輸入數組有點隨機。最後一列給出了以毫秒爲單位的時間。

+0

有趣的是'console.time()','console.timeEnd()'每隔幾個調用記錄'0.1n',然後'1.2n'? – guest271314

+0

@ guest271314,您可能需要使用更大的數據集重複測試。你有你的測試小提琴嗎? – trincot

+0

沒有嘗試與jsfiddle。使用stacksnippets,這可能是問題。還要注意,Question包含文本_「並刪除重複項」_,其中'.filter()'返回一個新數組,不會從原始數組中刪除重複項。 – guest271314