Как достичь максимальной эффективности с помощью карты подчеркивания и фильтра?
Можно ли комбинировать фильтр и карту Underscore? В настоящее время у меня есть два отдельных вызова функций, но мне интересно, могу ли я сделать их более эффективными, объединив их в один вызов. Как-то.
В основном у меня есть массив имен стран - я хочу отфильтровать их с помощью регулярного выражения, а затем отобразить отфильтрованные результаты в массив объектов 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']);
});
Любые другие советы для повышения эффективности также будут с благодарностью восприняты.
Ответы
Ответ 1
Вместо этого вы можете использовать each
:
result = []
_.each(array, function(elem) {
if(elem.indexOf(search) == 0)
result.push(...whatever...)
Также обратите внимание, что вам не нужно регулярное выражение, чтобы узнать, начинается ли строка с другой.
Ответ 2
Подчеркивание предлагает возможность цепочки с помощью _.chain
:
_.chain(allCountries)
.filter(function(n, i) { ... })
.map(function(n, i) { ... })
.value(); // stop chaining and get the result
Вместо re.exec(...) !== null
вы можете использовать re.test(...)
, и обратите внимание, что вам нужно избежать специальных символов регулярного выражения для searchString
.
Однако в этом простом случае лучше использовать .indexOf
, чтобы проверить, начинается ли строка с подстроки:
// substring should be apparent at position 0, discard case for both strings
return n.country.toLowerCase().indexOf(searchString.toLowerCase()) === 0;
Для строковых литералов .foo
может быть более четким, чем ['foo']
.
Ответ 3
Используйте _.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;
}, []);
Ответ 4
Ответ pimvdb - это то, как мы делаем что-то в функциональном программировании /underscore.js
это немного преждевременная оптимизация для выполнения обоих шагов в одно и то же время. JS не очень выигрывает от выполнения этих действий отдельно.
_.chain(allCountries)
.filter(function(n, i) { ... })
.map(function(n, i) { ... })
.value();
это очень легко понять, но как только мы начинаем комбинировать обязанности, все становится волосатым.
_. MapFilter (массив, filterFn, mapFn)...
с цепью мы жертвуем производительностью для производительности. Оба важны, но всегда один важнее другого. Мы не можем вернуться и повысить производительность, но после этого мы можем улучшить производительность.