Czy ktoś zna (jeśli to możliwe, również lodash) sposób grupowania tablicy obiektów za pomocą klucza obiektu, a następnie tworzenia nowej tablicy obiektów na podstawie grupowania? Na przykład mam tablicę obiektów samochodów:
var cars = [
{
'make': 'audi',
'model': 'r8',
'year': '2012'
}, {
'make': 'audi',
'model': 'rs5',
'year': '2013'
}, {
'make': 'ford',
'model': 'mustang',
'year': '2012'
}, {
'make': 'ford',
'model': 'fusion',
'year': '2015'
}, {
'make': 'kia',
'model': 'optima',
'year': '2012'
},
];
Chcę utworzyć nową tablicę obiektów samochodów pogrupowanych według make
:
var cars = {
'audi': [
{
'model': 'r8',
'year': '2012'
}, {
'model': 'rs5',
'year': '2013'
},
],
'ford': [
{
'model': 'mustang',
'year': '2012'
}, {
'model': 'fusion',
'year': '2015'
}
],
'kia': [
{
'model': 'optima',
'year': '2012'
}
]
}
groupBy
?Odpowiedzi:
Odpowiedź Timo brzmi: jak bym to zrobił. Proste
_.groupBy
i pozwalają na pewne duplikacje obiektów w zgrupowanej strukturze.Jednak OP poprosił również o usunięcie zduplikowanych
make
kluczy. Jeśli chcesz iść na całość:Plony:
Jeśli chcesz to zrobić za pomocą Underscore.js, zwróć uwagę, że jego wersja
_.mapValues
nazywa się_.mapObject
.źródło
W zwykłym Javascript można by użyć
Array#reduce
obiektuźródło
result
wyniki?Object.entries
zi zapętlić pary klucz / wartość.make
zbioru danych po zgrupowaniu? Zajmuje dodatkową przestrzeń.Szukasz
_.groupBy()
.Usunięcie właściwości, według której grupujesz, z obiektów powinno być w razie potrzeby banalne:
Jako bonus otrzymujesz jeszcze ładniejszą składnię dzięki funkcjom strzałkowym ES6:
źródło
var grouped = _.groupBy(cars, 'make');
w ogóle nie potrzebujesz funkcji, jeśli akcesor jest prostą nazwą właściwości.Krótka wersja grupowania tablicy obiektów według określonego klucza w es6:
Dłuższa wersja:
Wydaje się, że pierwotne pytanie dotyczy grupowania samochodów według marki, ale pomija markę w każdej grupie. Więc odpowiedź wyglądałaby tak:
źródło
Oto Twoja własna
groupBy
funkcja, która jest uogólnieniem kodu z: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscoreźródło
źródło
Chciałbym zostawić
REAL GROUP BY
na przykład JS Array dokładnie tak samo to zadanie tutajźródło
Możesz spróbować zmodyfikować obiekt wewnątrz funkcji wywoływanej przez iterację przez _.groupBy func. Zauważ, że tablica źródłowa zmienia jego elementy!
źródło
make
właściwość, a także jest bardziej czytelna.Jest to również możliwe dzięki prostej
for
pętli:źródło
for ( let { TABLE_NAME, ...fields } of source) { result[TABLE_NAME] = result[TABLE_NAME] || []; result[TABLE_NAME].push({ ...fields }); }
W przypadkach, w których klucz może być zerowy i chcemy je zgrupować jako inne
źródło
Utwórz metodę, której można użyć ponownie
Następnie poniżej możesz grupować według dowolnych kryteriów
źródło
Wersja prototypowa również korzystająca z ES6. Zasadniczo wykorzystuje to funkcję redukuj do przekazania akumulatora i aktualnego elementu, który następnie używa tego do zbudowania "zgrupowanych" tablic na podstawie przekazanego klucza. wewnętrzna część redukcji może wyglądać na skomplikowaną, ale zasadniczo testuje, czy klucz przekazanego obiektu istnieje, a jeśli nie, tworzy pustą tablicę i dołącza bieżący element do tej nowo utworzonej tablicy, w przeciwnym razie używając rozkładówki operator przekazuje wszystkie obiekty bieżącej tablicy kluczy i dołącza bieżący element. Mam nadzieję, że to komuś pomoże!
źródło
Możesz także skorzystać z
array#forEach()
takiej metody:źródło
źródło
Po prostu spróbuj tego, który działa dobrze dla mnie.
let grouped = _.groupBy(cars, 'make');
źródło
Zrobiłem test porównawczy, aby przetestować wydajność każdego rozwiązania, które nie korzysta z zewnętrznych bibliotek.
JSBen.ch
reduce()
Opcja, wysłane przez @Nina Scholza wydaje się być jedna optymalna.źródło
Podobała mi się odpowiedź @metakunfu, ale nie zapewnia ona dokładnie oczekiwanych wyników. Oto aktualizacja, która usuwa słowo „make” w końcowym ładunku JSON.
Wynik:
źródło
Dzięki lodash / fp możesz utworzyć funkcję z
_.flow()
pierwszą grupą za pomocą klucza, a następnie mapować każdą grupę i pomijać klucz z każdej pozycji:źródło
Opierając się na odpowiedzi @Jonas_Wilms, jeśli nie chcesz wpisywać wszystkich pól:
Nie wykonałem żadnego testu porównawczego, ale uważam, że użycie pętli for byłoby bardziej wydajne niż cokolwiek sugerowanego w tej odpowiedzi .
źródło
źródło
Zgrupowana tablica obiektów w maszynopisie z tym:
źródło
Uwielbiam pisać to bez zależności / złożoności, tylko po prostu proste js.
źródło
Oto inne rozwiązanie tego problemu. Zgodnie z prośbą.
Wynik:
źródło
Oto rozwiązanie zainspirowane Collectors.groupingBy () w Javie:
To da obiekt Map.
źródło