Как достичь максимальной эффективности с помощью карты подчеркивания и фильтра? - программирование
Подтвердить что ты не робот

Как достичь максимальной эффективности с помощью карты подчеркивания и фильтра?

Можно ли комбинировать фильтр и карту 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']);
});

Любые другие советы для повышения эффективности также будут с благодарностью восприняты.

4b9b3361

Ответ 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)...

с цепью мы жертвуем производительностью для производительности. Оба важны, но всегда один важнее другого. Мы не можем вернуться и повысить производительность, но после этого мы можем улучшить производительность.