Mam obiekt, który zawiera tablicę obiektów.
things = new Object();
things.thing = new Array();
things.thing.push({place:"here",name:"stuff"});
things.thing.push({place:"there",name:"morestuff"});
things.thing.push({place:"there",name:"morestuff"});
Zastanawiam się, jaka jest najlepsza metoda usuwania zduplikowanych obiektów z tablicy. Na przykład rzeczy. Wszystko stałoby się ...
{place:"here",name:"stuff"},
{place:"there",name:"morestuff"}
javascript
arrays
object
duplicates
Travis
źródło
źródło
aaaaa.aaaa.push(...)
:)Odpowiedzi:
Prymitywną metodą byłoby:
źródło
Co powiesz na
es6
magię?Referencyjny adres URL
Bardziej ogólnym rozwiązaniem byłoby:
Przykład Stackblitz
źródło
things.thing = things.thing.filter((thing, index, self) => self.findIndex(t => t.place === thing.place && t.name === thing.name) === index)
const uniqueArray = arrayOfObjects.filter((object,index) => index === arrayOfObjects.findIndex(obj => JSON.stringify(obj) === JSON.stringify(object)));
jsfiddle.net/x9ku0p7L/28Jeśli możesz korzystać z bibliotek Javascript, takich jak podkreślenie lub lodash, polecam przyjrzeć się
_.uniq
funkcji w ich bibliotekach. Odlodash
:Zasadniczo przekazujesz tablicę, która tutaj jest literałem obiektu, i przekazujesz atrybut, z którym chcesz usunąć duplikaty w oryginalnej tablicy danych, jak poniżej:
AKTUALIZACJA : Lodash teraz również wprowadził
.uniqBy
.źródło
uniqBy
zamiastuniq
np._.uniqBy(data, 'name')
... dokumentacji: lodash.com/docs#uniqByMiałem dokładnie ten sam wymóg, aby usunąć zduplikowane obiekty w tablicy na podstawie duplikatów na jednym polu. Znalazłem kod tutaj: JavaScript: Usuń duplikaty z tablicy obiektów
Tak więc w moim przykładzie usuwam z tablicy dowolny obiekt, który ma zduplikowaną wartość ciągu licenseNum.
Wyniki:
UniqueArray to:
źródło
for(var i in array) { if(array[i][prop]){ //valid lookupObject[array[i][prop]] = array[i]; } else { console.log('falsy object'); } }
for (let i in originalArray) { if (lookupObject[originalArray[i]['id']] === undefined) { newArray.push(originalArray[i]); } lookupObject[originalArray[i]['id']] = originalArray[i]; }
Najkrótsza jedna wkładka do ES6 +
Znajdź unikalne
id
w tablicy.Unikatowy dzięki wielu właściwościom (
place
iname
)Unikatowy dla wszystkich właściwości (To będzie wolne dla dużych tablic)
Zachowaj ostatnie wystąpienie.
źródło
Jedna wkładka przy użyciu zestawu
Wyjaśnienie:
new Set(myData.map(JSON.stringify))
tworzy obiekt Set przy użyciu strunowanych elementów myData.źródło
Używając ES6 + w jednym wierszu, możesz uzyskać unikalną listę obiektów według klucza:
Można go włączyć w funkcję:
Oto działający przykład:
Jak to działa
Najpierw tablica jest odwzorowywana w taki sposób, że może być używana jako dane wejściowe dla mapy.
co oznacza, że każdy element tablicy zostanie przekształcony w inną tablicę z 2 elementami; wybrany klucz jako pierwszego elementu i całej początkowej pozycji jako drugi element, nazywa wpisu (np. wpisy tablic , wpisy map ). A oto oficjalny dokument z przykładem pokazującym, jak dodawać wpisy tablicy w Konstruktorze map.
Przykład, kiedy kluczem jest miejsce :
Po drugie, przekazujemy tę zmodyfikowaną tablicę konstruktorowi mapy i oto dzieje się magia. Mapa wyeliminuje zduplikowane wartości kluczy, zachowując tylko ostatnią wstawioną wartość tego samego klucza. Uwaga : Mapa zachowuje kolejność wstawiania. ( sprawdź różnicę między mapą a obiektem )
Po trzecie, używamy wartości mapy, aby odzyskać oryginalne elementy, ale tym razem bez duplikatów.
Ostatnim jest dodanie tych wartości do nowej, nowej tablicy, aby mogła wyglądać jak struktura początkowa i zwracać:
źródło
id
. Pytanie wymaga, aby cały obiekt był unikalny we wszystkich dziedzinach, takich jakplace
iname
Oto kolejna opcja, aby to zrobić za pomocą metod iteracyjnych Array, jeśli potrzebujesz porównania tylko przez jedno pole obiektu:
źródło
jedna wkładka jest tutaj
źródło
Jeśli możesz poczekać na wyeliminowanie duplikatów, aż po wszystkich dodatkach, typowym podejściem jest najpierw posortowanie tablicy, a następnie wyeliminowanie duplikatów. Sortowanie pozwala uniknąć podejścia N * N polegającego na skanowaniu tablicy dla każdego elementu podczas ich przechodzenia.
Funkcja „eliminuj duplikaty” jest zwykle nazywana unikalną lub uniq . Niektóre istniejące implementacje mogą łączyć dwa etapy, np . Uniq prototypu
Ten post ma kilka pomysłów do wypróbowania (i niektórych, których należy unikać :-)), jeśli twoja biblioteka jeszcze go nie ma ! Osobiście uważam, że ten jest najprostszy:
źródło
function(_a,_b){return _a.a===_b.a && _a.b===_b.b;}
wówczas tablica nie zostanie posortowana.Najprostszym sposobem jest użycie
filter
:źródło
id
. Pytanie wymaga, aby cały obiekt był unikalny we wszystkich dziedzinach, takich jakplace
iname
Jest to ogólny sposób: przekazywanie funkcji sprawdzającej, czy dwa elementy tablicy są równe. W tym przypadku porównuje wartości
name
iplace
właściwości dwóch porównywanych obiektów.Odpowiedź ES5
Oryginalna odpowiedź ES3
źródło
Aby dodać jeszcze jeden do listy. Korzystanie z ES6 i
Array.reduce
przy pomocyArray.find
.W tym przykładzie filtrowanie obiektów na podstawie
guid
właściwości.Rozszerzenie tej opcji, aby umożliwić wybór właściwości i spakowanie jej w jedną warstwę:
Aby z niego skorzystać, przekaż tablicę obiektów i nazwę klucza, który chcesz wyodrębnić jako wartość ciągu:
źródło
Możesz również użyć
Map
:Pełna próbka:
Wynik:
źródło
Cholera, dzieciaki, zmiażdżmy to, dlaczego nie?
źródło
id
. Pytanie wymaga, aby cały obiekt był unikalny we wszystkich dziedzinach, takich jakplace
iname
place
iname
dzisiaj. Każdy, kto czyta ten wątek, szuka optymalnego sposobu na deduplikację listy obiektów, a jest to kompaktowy sposób na zrobienie tego.Rozwiązanie TypeScript
Spowoduje to usunięcie zduplikowanych obiektów, a także zachowanie typów obiektów.
źródło
Wobec
lodash.uniqWith
źródło
Inną opcją byłoby utworzenie niestandardowej funkcji indexOf, która porównuje wartości wybranej właściwości dla każdego obiektu i zawija ją w funkcji redukcji.
źródło
lodash.isequal
pakietem npm jako lekki komparator obiektów, aby wykonać unikalne filtrowanie macierzy ... np. odrębny zestaw obiektów. Właśnie zamieniłem sięif (_.isEqual(a[i], b)) {
zamiast szukać @ pojedynczej nieruchomościJednowarstwowy przy użyciu ES6 i
new Map()
.Detale:-
.map()
na liście danych i konwertując każdy pojedynczy obiekt na[key, value]
tablicę par (długość = 2), pierwszy element (klucz) byłbystringified
wersją obiektu, a drugi (wartość) byłbyobject
sam.new Map()
miałoby klucz jakostringified
obiekt, a każde dodanie tego samego klucza spowodowałoby zastąpienie już istniejącego klucza..values()
dałoby MapIterator ze wszystkimi wartościami na mapie (obj
w naszym przypadku)spread ...
operator podaje nową tablicę z wartościami z powyższego kroku.źródło
Oto rozwiązanie dla es6, w którym chcesz tylko zatrzymać ostatni przedmiot. To rozwiązanie jest funkcjonalne i zgodne ze stylem Airbnb.
źródło
removeDuplicates () przyjmuje tablicę obiektów i zwraca nową tablicę bez żadnych zduplikowanych obiektów (na podstawie właściwości id).
Spodziewany rezultat:
Najpierw ustawiamy wartość zmiennej uniq na pusty obiekt.
Następnie filtrujemy przez tablicę obiektów. Filtr tworzy nową tablicę ze wszystkimi elementami, które pomyślnie przejdą test zaimplementowany przez podaną funkcję.
Powyżej korzystamy z funkcji zwierania &&. Jeśli lewa strona && ma wartość true, to zwraca wartość po prawej stronie &&. Jeśli lewa strona jest fałszywa, zwraca to, co znajduje się po lewej stronie &&.
Dla każdego obiektu (obj) sprawdzamy uniq pod kątem właściwości o nazwie obj.id (W tym przypadku przy pierwszej iteracji sprawdzałby właściwość „1”). Chcemy, aby było odwrotnie niż to, co zwraca (prawda lub false), dlatego używamy! w! uniq [obj.id]. Jeśli uniq ma już właściwość id, zwraca true, co daje wartość false (!), Informując funkcję filtrującą, aby NIE dodawała tego obj. Jeśli jednak nie znajdzie właściwości obj.id, zwraca false, która następnie zwraca wartość true (!) I zwraca wszystko po prawej stronie && lub (uniq [obj.id] = true). Jest to prawdziwa wartość, która mówi metodzie filter, aby dodała ten obiekt do zwracanej tablicy, a także dodaje właściwość {1: true} do uniq. Dzięki temu żadna inna instancja obj o tym samym identyfikatorze nie zostanie dodana ponownie.
źródło
źródło
Uważam, że połączenie
reduce
z,JSON.stringify
aby idealnie porównać obiekty i selektywne dodawanie tych, którzy nie są jeszcze w akumulatorze, jest eleganckim sposobem.Należy pamiętać, że
JSON.stringify
może to stanowić problem z wydajnością w skrajnych przypadkach, gdy tablica zawiera wiele obiektów i są one złożone, ALE przez większość czasu jest to najkrótsza droga do przejścia na IMHO.Inny sposób pisania tego samego (ale mniej wydajnego):
źródło
Kontynuacja eksploracji sposobów usuwania duplikatów z tablicy obiektów ES6: ustawienie
thisArg
argumentuArray.prototype.filter
nanew Set
zapewnia przyzwoitą alternatywę:Jednak nie będzie działać z funkcjami strzałek
() =>
, ponieważthis
jest to związane z ich zakresem leksykalnym.źródło
Magia es6 w jednej linii ... czytelna!
źródło
Proste rozwiązanie z metodami pomocniczymi macierzy ES6 „zmniejsz” i „znajdź”
Działa wydajnie i idealnie dobrze!
źródło
Jeśli nie masz nic przeciwko posortowaniu unikalnej tablicy, byłoby to skuteczne rozwiązanie:
W ten sposób wystarczy porównać bieżący element z poprzednim elementem w tablicy. Sortowanie raz przed filtrowaniem (
O(n*log(n))
) jest tańsze niż wyszukiwanie duplikatu w całej tablicy dla każdego elementu tablicy (O(n²)
).źródło
Jest to prosty sposób na usunięcie duplikatu z tablicy obiektów.
Dużo pracuję z danymi i jest to dla mnie przydatne.
wypisze w konsoli:
źródło
str to tablica obiektów. Istnieją obiekty o tej samej wartości (tutaj mały przykład, są dwa obiekty o tym samym item_id jak 2). check (id) to funkcja, która sprawdza, czy istnieje obiekt o tym samym identyfikatorze elementu. jeśli istnieje, zwróć false, w przeciwnym razie zwróć true. Zgodnie z tym wynikiem wciśnij obiekt do nowej tablicy obj . Wyjście powyższego kodu to
[{"item_id":1},{"item_id":2}]
źródło
Czy słyszałeś o bibliotece Lodash? Polecam to narzędzie, gdy tak naprawdę nie chcesz zastosować swojej logiki do kodu i użyć już obecnego kodu, który jest zoptymalizowany i niezawodny.
Rozważ utworzenie takiej tablicy
Zauważ, że jeśli chcesz zachować unikalny atrybut, możesz to zrobić za pomocą biblioteki lodash. Tutaj możesz użyć _.uniqBy
Ta metoda jest podobna do _.uniq (która zwraca pozbawioną duplikatów wersję tablicy, w której zachowane jest tylko pierwsze wystąpienie każdego elementu), z tym wyjątkiem, że akceptuje iterat, który jest wywoływany dla każdego elementu w tablicy w celu wygenerowania kryterium, według którego wyjątkowość jest obliczana.
Na przykład, jeśli chcesz zwrócić tablicę posiadającą unikalny atrybut „miejsce”
Podobnie, jeśli chcesz unikalny atrybut jako „nazwa”
Mam nadzieję że to pomoże.
Twoje zdrowie!
źródło