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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 07:40:11  来源:igfitidea点击:

How to achieve maximum efficiency with underscore's map and filter?

javascriptunderscore.js

提问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 eachinstead:

您可以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(...) !== nullyou 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 .indexOfto 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, .foomay be clearer than ['foo'].

对于字符串文字,.foo可能比['foo'].

回答by Casey Foster

Use _.reduceas it saves niterations. Pull your RegEx out of the loop so you don't recreate the object every iteration. Use testinstead 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.

通过链接,我们正在牺牲性能以换取生产力。两者都很重要,但总是一个比另一个更重要。我们不能回头提高生产力,但我们可以事后提高绩效。