Eu tenho uma matriz de objetos que quero iterar para produzir uma nova matriz filtrada. Mas também preciso filtrar alguns objetos da nova matriz, dependendo de um parâmetro. Estou tentando isso:
function renderOptions(options) {
return options.map(function (option) {
if (!option.assigned) {
return (someNewObject);
}
});
}
Essa é uma boa abordagem? Há um método melhor? Estou aberto a usar qualquer biblioteca como o lodash.
javascript
arrays
Daniel Calderon Mori
fonte
fonte
.reduce()
é definitivamente mais rápido do que fazer um.filter(...).map(...)
que eu vi sugerido em outro lugar. Criei um teste para demonstrar JSPerf stackoverflow.com/a/47877054/2379922Respostas:
Você deve usar
Array.reduce
para isso.Como alternativa, o redutor pode ser uma função pura, como esta
fonte
filtered
é um objeto. entãofiltered.push
é indefinido para mim.filtered
ser um objeto. Isso ocorreu porque eu não estava passando o "valor inicial" - a matriz vazia ([]
) após a função de redução. por exemplo, incorretovar reduced = options.reduce(function(filtered, option) { ... });
corretovar reduced = options.reduce(function(filtered, option) { ... }, []);
reduce
aqui, você poderia usar da mesma maneira,forEach
pois em todas as iterações você altera o arrayfiltered
e, portanto, não é totalmente funcional. Seria um evento mais legível e compacto.Use reduzir, Luke!
fonte
Desde 2019, o Array.prototype.flatMap é uma boa opção.
Na página MDN vinculada acima:
fonte
flatMap
foi recentemente apresentado e seu suporte ao navegador é limitado . Você pode usar o polyfill / calços oficiais: flatMap e flat .Com o ES6, você pode fazer isso muito brevemente:
options.filter(opt => !opt.assigned).map(opt => someNewObject)
fonte
Uma linha
reduce
com a sintaxe de propagação sofisticada do ES6 está aqui!fonte
result
... é comofilter(assigned).map(name)
solução #...assigned ? [name] : []
- pode ser mais legível como...(assigned ? [name] : [])
Eu faria um comentário, mas não tenho a reputação necessária. Uma pequena melhoria na resposta muito boa de Maxim Kuzmin para torná-lo mais eficiente:
Explicação
Em vez de espalhar o resultado inteiro repetidamente para cada iteração, apenas anexamos à matriz e somente quando há realmente um valor a ser inserido.
fonte
Use o próprio Array.prototy.filter
fonte
Em algum momento, não é mais fácil (ou tão fácil) usar um
forEach
No entanto, seria bom se houvesse uma função
malter()
oufap()
que combine as funçõesmap
efilter
. Funcionaria como um filtro, exceto que, em vez de retornar verdadeiro ou falso, retornaria qualquer objeto ou um nulo / indefinido.fonte
Otimizei as respostas com os seguintes pontos:
if (cond) { stmt; }
comocond && stmt;
Vou apresentar duas soluções, uma usando forEach , a outra usando o método reduzir :
Solução 1: Usando o forEach
Solução 2: usando reduzir
Deixo a você decidir qual solução escolher.
fonte
cond && stmt;
? Isso é muito mais difícil de ler e não oferece nenhum benefício.Usando reduzir, você pode fazer isso em uma função Array.prototype. Isso buscará todos os números pares de uma matriz.
Você pode usar o mesmo método e generalizá-lo para seus objetos, assim.
arr
agora conterá os objetos filtrados.fonte
O uso direto de
.reduce
pode ser difícil de ler, por isso recomendo criar uma função que gere o redutor para você:Use-o assim:
fonte