Saya memiliki 2 objek bersarang yang berbeda dan saya perlu tahu apakah mereka memiliki perbedaan dalam salah satu properti bersarang mereka.
var a = {};
var b = {};
a.prop1 = 2;
a.prop2 = { prop3: 2 };
b.prop1 = 2;
b.prop2 = { prop3: 3 };
Objek bisa menjadi jauh lebih kompleks dengan properti yang lebih bersarang. Tapi yang ini adalah contoh yang bagus. Saya memiliki opsi untuk menggunakan fungsi rekursif atau sesuatu dengan lodash ...
javascript
lodash
JLavoie
sumber
sumber
_.isEqual(value, other)
Melakukan perbandingan mendalam antara dua nilai untuk menentukan apakah mereka setara. lodash.com/docs#isEqualJawaban:
Solusi yang mudah dan elegan adalah menggunakan
_.isEqual
, yang melakukan perbandingan mendalam:Namun, solusi ini tidak menunjukkan properti mana yang berbeda.
http://jsfiddle.net/bdkeyn0h/
sumber
_.isEqual
bisa sangat rumit. Jika Anda menyalin objek dan mengubah beberapa nilai di sana itu akan tetap terlihat benar, karena rujukannya sama. Jadi seseorang harus berhati-hati menggunakan fungsi ini.Jika Anda perlu tahu properti mana yang berbeda, gunakan kurangi () :
sumber
_.reduce(a, (result, value, key) => _.isEqual(value, b[key]) ? result : result.concat(key), [])
untuk solusi satu baris ES6let edited = _.reduce(a, function(result, value, key) { return _.isEqual(value, b[key]) ? result : result.concat( { [key]: value } ); }, []);
Bagi siapa pun yang menemukan thread ini, inilah solusi yang lebih lengkap Ini akan membandingkan dua objek dan memberi Anda kunci dari semua properti yang hanya di object1 , hanya di object2 , atau keduanya di object1 dan object2 tetapi memiliki nilai yang berbeda :
Berikut ini contoh output:
Jika Anda tidak peduli dengan objek bersarang dan ingin melewatkan lodash, Anda dapat mengganti
_.isEqual
untuk perbandingan nilai normal, misalnyaobj1[key] === obj2[key]
.sumber
Berdasarkan jawaban Adam Boduch , saya menulis fungsi ini yang membandingkan dua objek dalam arti yang paling dalam , mengembalikan jalur yang memiliki nilai berbeda serta jalur yang hilang dari satu atau objek lain.
Kode ini tidak ditulis dengan efisiensi dalam pikiran, dan perbaikan dalam hal itu disambut baik, tetapi di sini adalah bentuk dasar:
Anda dapat mencoba kode menggunakan snippet ini (disarankan berjalan dalam mode halaman penuh):
Tampilkan cuplikan kode
sumber
b
menggunakanb.hasOwnProperty(key)
ataukey in b
, tidak denganb[key] != undefined
. Dengan versi lama yang digunakanb[key] != undefined
, fungsi mengembalikan diff yang salah untuk objek yang berisiundefined
, seperti padacompare({disabled: undefined}, {disabled: undefined})
. Bahkan, versi lama juga punya masalah dengannull
; Anda dapat menghindari masalah seperti itu dengan selalu menggunakan===
dan!==
bukannya==
dan!=
.Inilah solusi singkat:
sumber
[]
.Untuk menunjukkan secara berulang bagaimana suatu objek berbeda dengan yang lain, Anda dapat menggunakan _.reduce dikombinasikan dengan _.isEqual dan _.isPlainObject . Dalam hal ini Anda dapat membandingkan bagaimana a berbeda dengan b atau bagaimana b berbeda dengan:
sumber
_.isEqual
Metode penggunaan sederhana , ini akan bekerja untuk semua ...Jadi, jika Anda memiliki di bawah ini:
Jika Anda melakukannya:
_.isEqual(firstName, otherName);
,itu akan mengembalikan true
Dan jika
const fullName = {firstName: "Alireza", familyName: "Dezfoolian"};
Jika Anda melakukannya:
_.isEqual(firstName, fullName);
,akan kembali salah
sumber
Kode ini mengembalikan objek dengan semua properti yang memiliki nilai berbeda dan juga nilai dari kedua objek. Berguna untuk mencatat perbedaannya.
sumber
Tanpa menggunakan lodash / garis bawah, saya telah menulis kode ini dan berfungsi dengan baik bagi saya untuk perbandingan objek1 yang mendalam dengan objek2
sumber
Bandingkan secara mendalam menggunakan templat properti (bersarang) untuk memeriksa
Ini akan berfungsi di konsol. Dukungan array dapat ditambahkan jika diperlukan
sumber
Saya mengambil kode Adam Boduch untuk menghasilkan perbedaan yang dalam - ini sama sekali belum diuji tetapi potongannya ada di sana:
sumber
diff({}, { foo: 'lol', bar: { baz: true }}) // returns []
Seperti yang ditanyakan, inilah fungsi perbandingan objek rekursif. Dan sedikit lagi. Dengan asumsi bahwa penggunaan utama dari fungsi tersebut adalah inspeksi objek, saya punya sesuatu untuk dikatakan. Perbandingan mendalam yang lengkap adalah ide yang buruk ketika beberapa perbedaan tidak relevan. Sebagai contoh, perbandingan yang dalam pada pernyataan TDD membuat tes tidak rapuh. Untuk alasan itu, saya ingin memperkenalkan diff parsial yang jauh lebih berharga . Ini adalah analog rekursif dari kontribusi sebelumnya ke utas ini. Ini mengabaikan kunci yang tidak ada dalam a
BDiff memungkinkan pengecekan nilai yang diharapkan sambil mentoleransi properti lain, yang persis seperti yang Anda inginkan untuk inspeksi otomatis . Ini memungkinkan membangun semua jenis pernyataan tingkat lanjut. Sebagai contoh:
Kembali ke solusi lengkap. Membangun diff tradisional penuh dengan bdiff itu sepele:
Menjalankan fungsi di atas pada dua objek kompleks akan menghasilkan sesuatu yang mirip dengan ini:
Akhirnya, untuk melihat bagaimana perbedaan nilai, kita mungkin ingin langsung mengevaluasi () output diff. Untuk itu, kita memerlukan versi jelek dari bdiff yang menghasilkan jalur yang benar secara sintaksis:
Itu akan menghasilkan sesuatu yang mirip dengan ini:
Lisensi MIT;)
sumber
Melengkapi jawaban dari Adam Boduch, yang ini memperhitungkan perbedaan dalam sifat
sumber
Jika Anda hanya perlu perbandingan kunci:
sumber
Berikut adalah skrip sederhana dengan Lodash deep difference checker yang akan menghasilkan objek baru dengan hanya perbedaan antara objek lama dan objek baru.
Misalnya, jika kita punya:
objek yang dihasilkan adalah:
Ini juga kompatibel dengan objek mendalam multi-level, untuk array mungkin perlu beberapa penyesuaian.
sumber
sumber
===
langsung,{ a: 20 } === { a: 20 }
akan mengembalikan false, karena membandingkan prototipe. Cara yang lebih tepat untuk membandingkan objek adalah dengan membungkusnyaJSON.stringify()
_.isEqual(f, s)
? :)f
adalah sebuah objek dan Anda mendapatkanif (_.isObject(f))
Anda hanya kembali melalui fungsi dan tekan titik itu lagi. Sama berlaku untukf (Array.isArray(f)&&Array.isArray(s))
ini berdasarkan @JLavoie , menggunakan lodash
https://jsfiddle.net/EmilianoBarboza/0g0sn3b9/8/
sumber
hanya menggunakan vanilla js
sumber
Untuk membangun berdasarkan jawaban Sridhar Gudimela , ini dia diperbarui dengan cara yang akan membuat Flow bahagia:
sumber