Mam tablicę obiektów, która wygląda następująco:
var array = [
{id:123, value:"value1", name:"Name1"},
{id:124, value:"value2", name:"Name1"},
{id:125, value:"value3", name:"Name2"},
{id:126, value:"value4", name:"Name2"}
...
];
Jak widać, niektóre nazwy się powtarzają. Chcę uzyskać nową tablicę tylko z nazwami, ale jeśli jakaś nazwa się powtarza, nie chcę jej ponownie dodawać. Chcę tę tablicę:
var newArray = ["Name1", "Name2"];
Próbuję to zrobić z map
:
var newArray = array.map((a) => {
return a.name;
});
Problem w tym, że to zwraca:
newArray = ["Name1", "Name1", "Name2", "Name2"];
Jak mogę ustawić warunek w środku map
, aby nie zwracał elementu, który już istnieje? Chcę to zrobić za pomocą map
lub innej funkcji ECMAScript 5 lub ECMAScript 6.
javascript
arrays
snoopy25
źródło
źródło
Set
? developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Odpowiedzi:
W ES6 można było używać
Set
unikalnych wartości, po odwzorowaniu tylko nazw obiektów.Ta propozycja wykorzystuje składnię rozkładówek
...
do gromadzenia elementów w nowej tablicy.źródło
...
?...
służąca do budowania tablicy z iterowalnym obiektem.Array.from
znacznie lepiej oddaje zamiar konwersji (a także jest łatwiejsze do zrozumienia / wyszukania początkujących), składnia rozprzestrzeniania powinna być używana tylko wtedy, gdy rozproszony element jest jednym z wielu. Może nazwanie tego „złą praktyką” jest trochę zbyt surowe, przepraszam, mam tylko nadzieję, że nie stanie się to powszechnym idiomem.Jeśli szukasz rozwiązania JavaScript innego niż ES 6 (brak zestawu), możesz skorzystać z metody Array
reduce
:źródło
var names = array.reduce(function(a, b) { a.indexOf(b.name) === -1 && a.push(b.name) return a; }, []);
Osobiście nie rozumiem, dlaczego wszyscy polubią ES 6. Gdyby to był mój kod, wolałbym obsługiwać jak najwięcej przeglądarek.
źródło
indexOf
ciągłego -ing? Np. Zróbadded[name] = true
iif(added[name])
zamiastif(a.indexOf(name))
.goto fail
, przeciekając zmienną indeksu do otaczającego zakresu, itp. itd. ES6 został zakodowany w standardzie z ważnych powodów i jest w większości częściowo łatwe do wypełnienia / przekształcenia w starszych przeglądarkach.Możesz też po prostu połączyć
map
zfilter
źródło
Możesz użyć Object.keys (), aby uzyskać tablicę własnych wyliczalnych nazw właściwości danego obiektu z wyniku iteracji
array
zmiennej za pomocą Array.prototype.reduce (), gdzie klucze są zniszczonymi nazwamiKod:
źródło
Wiele dobrych odpowiedzi tutaj. Chciałbym tylko wnieść swój wkład z pewną różnorodnością, mając nadzieję, że dam wam inną perspektywę.
Tablice są typu obiektowego w JavaScript, więc mogą być używane jednocześnie jako hash. Korzystając z tej funkcjonalności, możemy znacznie uprościć zadanie do wykonania w pojedynczej operacji zredukowanej o złożoności O (n) czasowej.
Jeśli nie jesteś zadowolony z tablicy zawierającej inne właściwości niż klucze tablicy, możesz również rozważyć pozostawienie oddzielnego obiektu skrótu.
źródło
p[c.name]
na osobnym przedmiocie,o
a następnie wyrzucenie go.Zgadzam się, że jeśli potrzebujesz tylko
name
wartości, drogaSet
jest drogą.Jednakże , jeśli chcesz uzyskać szereg unikatowych obiektów w oparciu o
name
właściwości, sugeruję, aby użyćMap
. Szybkim sposobem na utworzenie mapy jest użycie tablicy[key, value]
tablic:Dodatkową korzyścią
Map
jest to, że otrzymujesz zarównofilter
funkcjonalność, która eliminuje nieuniknione elementy, bez utraty połączenia z obiektami źródłowymi. Oczywiście jest to potrzebne tylko wtedy, gdy chcesz wielokrotnie odwoływać się do unikalnego zestawu obiektów.źródło
Jeśli jesteś ograniczony do ES5, użyłbym Lodash
_.uniq
źródło
W przypadku ES6 powinno to wystarczyć.
źródło
map
ma być używany z czystymi funkcjami i nie powodować skutków ubocznych. To byłaby praca dlaforEach
lubreduce
.Używając UnderscoreJS,
`
źródło
W ES5 użyj obiektu jako słownika dla wydajności O ( n ).
Działa to tylko wtedy, gdy wszystkie klucze są ciągami.
Możesz zrobić to samo w jednym wyrażeniu, jeśli chcesz:
ale uważam, że rozkazujący formularz jest łatwiejszy do odczytania.
źródło
function (item) { return item.name; }
Object.keys()
, ta odpowiedź używafilter()
do zachowania tylko tych nazw, które nie zostały jeszcze zapisane na mapie, co jest dość eleganckie.Spróbuj tego:
źródło
Użyj
array#forEach()
iarray#indexOf()
metod takich jak ta, jeśli chcesz jeszcze maksymalną kompatybilność , zwięzłą składnię:Jednakże, jeśli zgodność jest nie problem użycie ECMAScript 6 „s
Set
obiektu,array#map
orazArray.from()
sposoby jak to:źródło
Tak to zrobiłem, używając oddzielnej pustej tablicy.
źródło
Dla osób poszukujących 1 wkładki
lub bez użycia metod na prototypie tablicy
może się przydać do napisania czystych funkcji do radzenia sobie z tym
źródło
źródło