У меня есть массив объектов, которые я хочу перебрать, чтобы создать новый фильтрованный массив. Но также мне нужно отфильтровать некоторые объекты из нового массива в зависимости от параметра. Я пытаюсь это:
function renderOptions(options) {
return options.map(function (option) {
if (!option.assigned) {
return (someNewObject);
}
});
}
Это хороший подход? Есть ли лучший метод? Я открыт, чтобы использовать любую библиотеку, такую как lodash.
javascript
arrays
Даниэль Кальдерон Мори
источник
источник
.reduce()
определенно быстрее, чем делать то,.filter(...).map(...)
что я видел в другом месте. Я настроил тест JSPerf для демонстрации stackoverflow.com/a/47877054/2379922Ответы:
Вы должны использовать
Array.reduce
для этого.В качестве альтернативы, редуктор может быть чистой функцией, как это
источник
filtered
- это объект. такfiltered.push
не определено для меня.filtered
чтобы быть объектом. Это было потому, что я не передавал «начальное значение» - пустой массив ([]
) после функции Reduce. например, неверноvar reduced = options.reduce(function(filtered, option) { ... });
правильноvar reduced = options.reduce(function(filtered, option) { ... }, []);
reduce
, вы также можете использовать его,forEach
так как на каждой итерации вы меняете массивfiltered
и, следовательно, он не является чисто функциональным. Это было бы событие более читабельным и компактным.Используйте уменьшить, Люк!
источник
С 2019 года Array.prototype.flatMap является хорошим вариантом.
Со страницы MDN, указанной выше:
источник
flatMap
было недавно введено, и его поддержка браузера ограничена . Вы можете использовать официальные полифилы / прокладки: flatMap и flat .С ES6 вы можете сделать это очень коротко:
options.filter(opt => !opt.assigned).map(opt => someNewObject)
источник
Одна строка
reduce
с необычным синтаксисом ES6 здесь!источник
result
... это какfilter(assigned).map(name)
решение...assigned ? [name] : []
- это может быть более читабельным, как...(assigned ? [name] : [])
Я бы сделал комментарий, но у меня нет необходимой репутации. Небольшое улучшение в отличном ответе Максима Кузьмина, чтобы сделать его более эффективным:
объяснение
Вместо того, чтобы распространять весь результат снова и снова для каждой итерации, мы добавляем только массив, и только тогда, когда на самом деле есть значение для вставки.
источник
Используйте сам Array.prototy.filter
источник
В какой-то момент, не так ли просто (или просто) использовать
forEach
Однако было бы хорошо , если бы там был
malter()
илиfap()
функция , которая сочетает вmap
иfilter
функции. Он будет работать как фильтр, за исключением того, что вместо возврата true или false он будет возвращать любой объект или null / undefined.источник
Я оптимизировал ответы со следующими пунктами:
if (cond) { stmt; }
какcond && stmt;
Я представлю два решения, одно с использованием forEach , другое с использованием Reduce :
Решение 1. Использование forEach
Решение 2: Использование Reduce
Я оставляю на ваше усмотрение решать, какое решение выбрать.
источник
cond && stmt;
? Это гораздо сложнее для чтения и не дает никаких преимуществ вообще.Используя Reduce, вы можете сделать это в одной функции Array.prototype. Это позволит получить все четные числа из массива.
Вы можете использовать тот же метод и обобщить его для ваших объектов, например так.
arr
теперь будет содержать отфильтрованные объекты.источник
Непосредственное использование
.reduce
может быть трудночитаемым, поэтому я рекомендую создать функцию, которая генерирует редуктор для вас:Используйте это так:
источник