2016-11-10 39 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