Mam 2 zagnieżdżone obiekty, które są różne i muszę wiedzieć, czy różnią się jedną z ich zagnieżdżonych właściwości.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
Obiekt może być znacznie bardziej złożony z większą liczbą zagnieżdżonych właściwości. Ale ten jest dobrym przykładem. Mam opcję korzystania z funkcji rekurencyjnych lub czegoś podobnego do lodash ...
javascript
lodash
JLavoie
źródło
źródło
_.isEqual(value, other)
Przeprowadza dokładne porównanie dwóch wartości, aby ustalić, czy są one równoważne. lodash.com/docs#isEqualOdpowiedzi:
Łatwym i eleganckim rozwiązaniem jest użycie
_.isEqual
, które umożliwia dokładne porównanie:Jednak to rozwiązanie nie pokazuje, która właściwość jest inna.
http://jsfiddle.net/bdkeyn0h/
źródło
_.isEqual
może być dość trudna. Jeśli skopiujesz obiekt i zmienisz tam niektóre wartości, nadal będzie to prawda, ponieważ odwołanie jest takie samo. Dlatego należy zachować ostrożność podczas korzystania z tej funkcji.Jeśli chcesz wiedzieć, które właściwości są różne, użyj funkcji zmniejsz () :
źródło
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
dlalet edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Dla każdego, kto natknie się na ten wątek, oto bardziej kompletne rozwiązanie. Porówna dwa obiekty i poda klucz wszystkich właściwości, które są albo tylko w obiekcie object1 , tylko w obiekcie object2 , albo oba są w obiektach object1 i object2, ale mają różne wartości :
Oto przykładowy wynik:
Jeśli nie zależy Ci na zagnieżdżonych obiektach i chcesz pominąć lodash, możesz zastąpić
_.isEqual
porównanie wartości normalnej, npobj1[key] === obj2[key]
.źródło
Na podstawie odpowiedzi Adama Boducha napisałem tę funkcję, która porównuje dwa obiekty w najgłębszym możliwym sensie , zwracając ścieżki o różnych wartościach, a także ścieżki, których brakuje w jednym lub drugim obiekcie.
Kod nie został napisany z myślą o wydajności, a ulepszenia w tym zakresie są mile widziane, ale oto podstawowa forma:
Możesz wypróbować kod za pomocą tego fragmentu kodu (zalecane jest uruchomienie w trybie pełnej strony):
Pokaż fragment kodu
źródło
b
za pomocąb.hasOwnProperty(key)
lubkey in b
nieb[key] != undefined
. W poprzedniej używanej wersjib[key] != undefined
funkcja zwróciła niepoprawną różnicę dla obiektów zawierającychundefined
, jak wcompare({disabled: undefined}, {disabled: undefined})
. W rzeczywistości stara wersja również miała problemynull
; możesz uniknąć takich problemów, zawsze używając===
i!==
zamiast==
i!=
.Oto zwięzłe rozwiązanie:
źródło
[]
.Aby rekurencyjnie pokazać, jak obiekt różni się od innych, możesz użyć _.reduce w połączeniu z _.isEqual i _.isPlainObject . W takim przypadku możesz porównać, jak a różni się od b lub jak b różni się od a:
źródło
Prosta
_.isEqual
metoda użycia , będzie działać dla wszystkich porównujących ...Więc jeśli masz poniżej:
Jeśli tak:
_.isEqual(firstName, otherName);
,zwróci prawdę
I jeśli
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Jeśli tak:
_.isEqual(firstName, fullName);
,zwróci fałsz
źródło
Ten kod zwraca obiekt ze wszystkimi właściwościami, które mają inną wartość, a także wartości obu obiektów. Przydatne do rejestrowania różnicy.
źródło
Bez użycia lodash / podkreślenia napisałem ten kod i działa dobrze dla mnie do głębokiego porównania object1 z object2
źródło
Dokładne porównanie przy użyciu szablonu (zagnieżdżonych) właściwości do sprawdzenia
To zadziała w konsoli. W razie potrzeby można dodać obsługę tablicy
źródło
Wzięłam dźgnięcie kodem Adama Boducha, aby wyprowadzić głęboki plik różnicowy - jest to całkowicie niesprawdzone, ale fragmenty są:
źródło
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Jak zostało zadane, oto funkcja porównywania obiektów rekurencyjnych. I trochę więcej. Zakładając, że podstawowym zastosowaniem takiej funkcji jest kontrola obiektów, mam coś do powiedzenia. Całkowite dokładne porównanie jest złym pomysłem, gdy pewne różnice są nieistotne. Na przykład ślepe głębokie porównanie w stwierdzeniach TDD sprawia, że testy stają się niepotrzebne. Z tego powodu chciałbym wprowadzić o wiele bardziej wartościowy różnicowy fragment . Jest to rekurencyjny odpowiednik poprzedniego wkładu do tego wątku. Ignoruje klucze nie występujące w A
BDiff umożliwia sprawdzanie oczekiwanych wartości przy jednoczesnym tolerowaniu innych właściwości, co jest dokładnie tym, czego chcesz do automatycznej kontroli. Pozwala to na budowanie wszelkiego rodzaju zaawansowanych twierdzeń. Na przykład:
Wracając do kompletnego rozwiązania. Budowanie pełnego tradycyjnego diff z bdiff jest banalne:
Uruchomienie powyższej funkcji na dwóch złożonych obiektach spowoduje wyświetlenie czegoś podobnego do tego:
Na koniec, aby rzucić okiem na różnice między wartościami, możemy chcieć bezpośrednio ewaluować () wyjście diff. W tym celu potrzebujemy brzydszej wersji bdiff, która wyświetla poprawne składniowo ścieżki:
To da wynik podobny do tego:
Licencja MIT;)
źródło
Uzupełniając odpowiedź Adama Boducha, ta uwzględnia różnice we właściwościach
źródło
Jeśli potrzebujesz tylko klucza porównania:
źródło
Oto prosty maszynopis z funkcją sprawdzania głębokości różnic Lodash, która utworzy nowy obiekt z różnicami między starym a nowym obiektem.
Na przykład, gdybyśmy mieli:
wynikowy obiekt byłby:
Jest również kompatybilny z wielopoziomowymi głębokimi obiektami, w przypadku tablic może wymagać drobnych poprawek.
źródło
źródło
===
bezpośrednio porównywać obiektów ,{ a: 20 } === { a: 20 }
zwróci false, ponieważ porównuje prototyp. Bardziej właściwym sposobem przede wszystkim porównywania obiektów jest zawijanie ichJSON.stringify()
_.isEqual(f, s)
? :)f
jest obiektem i dojdziesz doif (_.isObject(f))
siebie, po prostu wróć przez funkcję i ponownie uderz w ten punkt. To samo dotyczyf (Array.isArray(f)&&Array.isArray(s))
było to oparte na @JLavoie , przy użyciu lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
źródło
tylko używając waniliowego js
źródło
Aby skorzystać z odpowiedzi Sridhara Gudimeli , tutaj jest ona aktualizowana w sposób, który uszczęśliwia Flow:
źródło