javascript 如何使用下划线的映射和过滤器实现最大效率?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9739324/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to achieve maximum efficiency with underscore's map and filter?
提问by Richard
Is it possible to combine Underscore's filter and map? I currently have two separate function calls, but I'm wondering if I can make them more efficient by combining them into a single call, somehow.
是否可以结合 Underscore 的过滤器和地图?我目前有两个单独的函数调用,但我想知道是否可以通过将它们组合成一个调用来提高它们的效率,不知何故。
Basically I have an array of country names - I want to filter them using a regex, then map the filtered results to an array of DataItem objects. This is my current code:
基本上我有一个国家名称数组 - 我想使用正则表达式过滤它们,然后将过滤后的结果映射到一个 DataItem 对象数组。这是我当前的代码:
var filteredData = _.filter(allCountries, function(n, i){
var re = RegExp("^" + searchString, "i");
if (re.exec(n['country'].toLowerCase()) !== null) {
return true;
}
});
var mappedData = _.map(filteredData, function(n, i){
return new DataItem(i, n['name'], n['budget']);
});
Any other tips for improved efficiency would also be gratefully received.
任何其他提高效率的提示也将不胜感激。
采纳答案by georg
You can use each
instead:
您可以each
改用:
result = []
_.each(array, function(elem) {
if(elem.indexOf(search) == 0)
result.push(...whatever...)
Also note that you don't need a regular expression just to find out if a string starts with another one.
另请注意,您不需要正则表达式来确定一个字符串是否以另一个字符串开头。
回答by pimvdb
Underscore offers a chaining ability through _.chain
:
下划线通过_.chain
以下方式提供链接能力:
_.chain(allCountries)
.filter(function(n, i) { ... })
.map(function(n, i) { ... })
.value(); // stop chaining and get the result
Instead of re.exec(...) !== null
you can use re.test(...)
, and note that you need to escape special regexp characters for searchString
.
而不是re.exec(...) !== null
您可以使用re.test(...)
, 并注意您需要转义特殊的正则表达式字符searchString
.
In this simple case however, it's better to use .indexOf
to check whether the string starts with a substring:
然而,在这个简单的情况下,最好使用.indexOf
检查字符串是否以子字符串开头:
// substring should be apparent at position 0, discard case for both strings
return n.country.toLowerCase().indexOf(searchString.toLowerCase()) === 0;
For string literals, .foo
may be clearer than ['foo']
.
对于字符串文字,.foo
可能比['foo']
.
回答by Casey Foster
Use _.reduce
as it saves n
iterations. Pull your RegEx out of the loop so you don't recreate the object every iteration. Use test
instead of exec
(faster because it's a simple boolean result).
使用_.reduce
它可以节省n
迭代。将您的 RegEx 拉出循环,这样您就不会每次迭代都重新创建对象。使用test
而不是exec
(更快,因为它是一个简单的布尔结果)。
var re = RegExp("^" + searchString, "i");
var data = _.reduce(allCountries, function(res, n, i) {
if (re.test(n['country'])) {
res.push(new DataItem(i, n['name'], n['budget']));
}
return res;
}, []);
回答by PPPaul
pimvdb's answer is the way we do things in functional programming/underscore.js it's a bit of a premature optimization to do both steps at the same time. JS doesn't benefit much from doing these things separately.
pimvdb 的答案是我们在函数式编程/underscore.js 中做事的方式,同时执行这两个步骤有点过早的优化。JS 并没有从单独做这些事情中受益。
_.chain(allCountries)
.filter(function(n, i) { ... })
.map(function(n, i) { ... })
.value();
the above is very easy to understand, but once we start combining responsibilities things get hairy.
上面的内容很容易理解,但是一旦我们开始组合职责,事情就会变得棘手。
_.mapFilter(array,filterFn,mapFn)...
_.mapFilter(array,filterFn,mapFn)...
with chaining we are sacrificing performance for productivity. Both are important, but always one is more important than the other. We can't go back and improve productivity, but we can improve performance after the fact.
通过链接,我们正在牺牲性能以换取生产力。两者都很重要,但总是一个比另一个更重要。我们不能回头提高生产力,但我们可以事后提高绩效。