Mam tablicę obiektów, które chcę iterować, aby utworzyć nową filtrowaną tablicę. Ale także muszę odfiltrować niektóre obiekty z nowej tablicy w zależności od parametru. Próbuję tego:
function renderOptions(options) {
return options.map(function (option) {
if (!option.assigned) {
return (someNewObject);
}
});
}
Czy to dobre podejście? Czy jest lepsza metoda? Jestem otwarty na korzystanie z dowolnej biblioteki, takiej jak lodash.
javascript
arrays
Daniel Calderon Mori
źródło
źródło
.reduce()
jest zdecydowanie szybszy niż zrobienie.filter(...).map(...)
tego, co sugerowałem gdzie indziej. Skonfigurowałem test JSPerf, aby zademonstrować stackoverflow.com/a/47877054/2379922Odpowiedzi:
Powinieneś użyć
Array.reduce
do tego.Alternatywnie, reduktor może być czystą funkcją, jak ta
źródło
filtered
to obiekt. więcfiltered.push
jest dla mnie niezdefiniowane.filtered
byciem obiektem. To dlatego, że nie przekazałem „wartości początkowej” - pustej tablicy ([]
) po funkcji redukuj. np. niepoprawnevar reduced = options.reduce(function(filtered, option) { ... });
poprawnevar reduced = options.reduce(function(filtered, option) { ... }, []);
reduce
tego, równie dobrze możesz go użyć,forEach
ponieważ w każdej iteracji zmieniasz tablicę,filtered
a zatem nie jest to czysta funkcjonalność. Byłoby to wydarzenie bardziej czytelne i zwięzłe.Użyj redukcji, Luke!
źródło
Od 2019 roku Array.prototype.flatMap jest dobrą opcją.
Z powyższej strony MDN:
źródło
flatMap
został niedawno wprowadzony, a jego obsługa przeglądarki jest ograniczona . Możesz użyć oficjalnego polyfill / shims : flatMap i flat .Z ES6 możesz to zrobić bardzo krótko:
options.filter(opt => !opt.assigned).map(opt => someNewObject)
źródło
Jedna linia
reduce
z fantazyjną składnią rozszerzania ES6 jest tutaj!źródło
result
... jest jakfilter(assigned).map(name)
rozwiązanie...assigned ? [name] : []
...(assigned ? [name] : [])
Zrobiłbym komentarz, ale nie mam wymaganej reputacji. Małe ulepszenie w stosunku do bardzo dobrej odpowiedzi Maxima Kuzmina, aby uczynić ją bardziej wydajną:
Wyjaśnienie
Zamiast rozprowadzać cały wynik w kółko dla każdej iteracji, dopisujemy tylko do tablicy i tylko wtedy, gdy faktycznie istnieje wartość do wstawienia.
źródło
Użyj samego Array.prototy.filter
źródło
W pewnym momencie, czy nie jest łatwiej (lub równie łatwo) używać pliku
forEach
Byłoby jednak miło, gdyby istniała funkcja
malter()
lubfap()
łącząca funkcjemap
ifilter
. Działałby jak filtr, z tą różnicą, że zamiast zwracać wartość true lub false, zwróciłby dowolny obiekt lub wartość null / undefined.źródło
Zoptymalizowałem odpowiedzi, uwzględniając następujące punkty:
if (cond) { stmt; }
jakocond && stmt;
Przedstawię dwa rozwiązania, jedno wykorzystujące forEach , drugie wykorzystujące redukuj :
Rozwiązanie 1: Korzystanie z forEach
Rozwiązanie 2: Korzystanie z programu Redukcja
Decyzja o wyborze rozwiązania pozostawiam Tobie.
źródło
cond && stmt;
? Jest to dużo trudniejsze do odczytania i nie daje żadnych korzyści.Używając redukuj, możesz to zrobić w jednej funkcji Array.prototype. Spowoduje to pobranie wszystkich liczb parzystych z tablicy.
Możesz użyć tej samej metody i uogólnić ją dla swoich obiektów, w ten sposób.
arr
będzie teraz zawierać przefiltrowane obiekty.źródło
Bezpośrednie użycie
.reduce
może być trudne do odczytania, dlatego polecam utworzenie funkcji, która generuje reduktor:Użyj go w ten sposób:
źródło