Underscore: _.union tidak berfungsi dengan array objek

Dibuat pada 2 Okt 2015  ·  32Komentar  ·  Sumber: jashkenas/underscore

_.union akan selalu menghasilkan duplikat ketika melewati array objek.

misalnya _.union( [ { a:1 } ], [ { a:1 } ]) akan mengembalikan [ { a:1 }, { a:1 } ]

Anehnya, fungsi isEqual garis bawah sendiri akan memberi tahu Anda bahwa objek yang dimaksud adalah sama. Mungkin kita bisa memiliki flag/opsi yang menentukan perbandingan kesetaraan untuk digunakan, atau opsi untuk meneruskan pembanding?

change

Komentar yang paling membantu

Utas ini menginspirasi saya untuk menambahkan _.intersectionWith , _.differenceWith , _.unionWith , dan _.uniqWith untuk menangani penyesuaian perbandingan dalam kode saya sendiri.

var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];

_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]

Semua 32 komentar

Saya terkejut itu belum menerima fungsi perbandingan. :+1:

Perlu ditunjukkan bahwa ini berlaku untuk semua fungsi komputasi array lainnya seperti perbedaan, persimpangan, unik, dll.

Akan lebih baik jika rangkaian lengkap fungsi array dapat diperbarui untuk memungkinkan penggunaan pembanding kesetaraan yang berbeda untuk objek.

Bukankah akan lebih mudah jika kita memiliki opsi yang membandingkan kesetaraan berdasarkan nilai parameter boolean yang dapat diteruskan ke fungsi _.union()? Jika benar maka secara otomatis akan membandingkan semua objek dalam array itu.

Misalnya _.union([1, 2, 3, 10, [{a:1}, {a:1}]], true) , akan menghasilkan [1,2,3,10, {a:1}]

@amiral84 Tidak. Itu tidak berhubungan. Jika Anda menginginkan perilaku tersebut, buatlah union dengan flatten.

@michaelficarra Lalu apakah saya melewatkan inti dari topik ini? :D

@amiral84 Tampaknya begitu. Permintaan fitur dijelaskan secara lengkap dan ringkas di komentar pertama.

masalah mendasar tampaknya ada di _.uniq karena _.union hanyalah fungsi pembungkus untuk unik dan rata.

_.union = restArgs(function(arrays) {
  return _.uniq(flatten(arrays, true, true));
});

Utas ini menginspirasi saya untuk menambahkan _.intersectionWith , _.differenceWith , _.unionWith , dan _.uniqWith untuk menangani penyesuaian perbandingan dalam kode saya sendiri.

var array = [ { 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }, { 'a': 1, 'b': 2 } ];

_.uniqWith(array, _.isEqual);
// => [{ 'a': 1, 'b': 2 }, { 'a': 1, 'b': 3 }]

atau sesuatu di sepanjang baris _.isCollection untuk menentukan apakah Anda berurusan dengan koleksi. Jika berurusan dengan koleksi, maka perbandingan harus menggunakan _.isEqual alih-alih === yang tidak baik dalam kasus koleksi.

@dperrymorrow

harus menggunakan _.isEqual alih-alih === yang tidak berguna dalam hal koleksi.

Peralihan dinamis terdengar seperti ide yang buruk. JS menggunakan perbandingan === atau SameValueZero untuk banyak hal. Jika ada kebutuhan untuk keluar dari perbandingan itu, sesuatu seperti _.uniqWith akan dilakukan.

Terima kasih untuk @jdalton ini, fungsi _opWith yang Anda sebutkan benar-benar sempurna untuk apa yang saya coba capai. Adakah ide kapan mereka akan tersedia melalui rilis?

@jdalton poin bagus tentang perbandingan, tetapi bukankah Anda biasanya menggunakan kunci untuk unik pada koleksi daripada memaksa Garis Bawah untuk mendeteksi seluruh perbedaan antara objek?

Bukankah yang berikut ini akan menyelesaikan permintaan @ wilhen01 _(walaupun lebih bertele-tele dari yang diinginkan)_

_.chain([{ a: 1 }]).union( [{a: 1}]).unique('a').value();
//=> [{a: 1}]

Bukankah yang berikut ini akan menyelesaikan permintaan @ wilhen01 (walaupun lebih bertele-tele dari yang diinginkan)

_.uniq sudah mendukung itu.

benar, itu maksud saya, kode di atas berfungsi saat ini seperti yang diposting.
tidak bisakah Anda memanggil uniq / unik dengan kunci pada hasil serikat?

@dperrymrow Pikirkan sedikit di luar contoh itu dan tambahkan properti lain .

ok, mengerti, maaf... Saya tidak mencoba untuk berperang, hanya ingin benar-benar memahami masalahnya. Saya ingin mengirimkan permintaan tarik pada fungsi _.uniqWith .

Jangan khawatir, itu akan menjadi rad.

_.intersectionWith, _.differenceWith, _.unionWith, dan _.uniqWith

Bukankah API yang lebih bagus hanya mengizinkan fungsi perbandingan untuk dilewatkan secara opsional sebagai argumen terakhir, alih-alih mencetak empat fungsi baru?

@jashkenas

Bukankah API yang lebih bagus hanya mengizinkan fungsi perbandingan untuk dilewatkan secara opsional sebagai argumen terakhir, alih-alih mencetak empat fungsi baru?

Ya, itu bisa dilakukan tetapi ada komplikasi karena metode seperti _.uniq sudah mendukung melewati iteratee dan sangat kelebihan beban dengan dukungan untuk flag pencarian biner/diurutkan dan parameter konteks juga . Ini berarti memperkenalkan arity sniffing yang terasa terlalu pintar untuk situasi ini. Ini juga akan memperumit upaya modularisasi di masa mendatang karena menggabungkan banyak fungsi opsional menjadi satu titik ketika implementasi dapat disederhanakan dan dipecah menjadi metode terpisah.

Benar, masalah desain yang sangat disayangkan. Tetapi membuat fungsi baru hanya untuk memungkinkan komparator juga tidak terasa seperti solusi yang tepat.

ok jadi parameter fungsi perbandingan tambahan adalah cara untuk pergi ke sini?
Jika demikian, saya dapat memperbarui permintaan tarik saya.

satu-satunya bagian rumit yang saya perkirakan adalah membuat parsing parameter sedikit lebih berbulu seperti @jdalton yang disebutkan di atas.

_.uniq = _.unique = function(array, isSorted, iteratee, context) {
  if (!_.isBoolean(isSorted)) {
    context = iteratee;
    iteratee = isSorted;
    isSorted = false;
  }
//...

Mungkin menambahkan pemeriksaan tambahan untuk melihat apakah isSorted _.isFunction kemudian memperlakukannya sebagai pembanding.

@jashkenas

Tetapi membuat fungsi baru hanya untuk memungkinkan komparator juga tidak terasa seperti solusi yang tepat.

Ini mungkin pilihan terbaik untuk situasi yang buruk. Saya telah mencoba memisahkan fungsionalitas yang kelebihan beban baru-baru ini dan cukup senang dengan hasilnya. Meskipun meningkatkan permukaan API, ini memungkinkan implementasi dan pengelompokan metode bertema serupa yang lebih sederhana seperti maxBy , uniqBy , pickBy , atau uniqWith , unionWith , zipWith , atau sortedIndexBy , sortedIndexOf , sortedUniq . Dalam kasus uniq meskipun saya masih menggunakan fungsi dasar bersama saat ini.

telah memperbarui permintaan tarik ini #2368 terima kasih.

Saya :+1: untuk uniqBy atau uniqWith . Saya akan sepenuhnya menentang kelebihan uniq lebih lanjut (seperti #2368 saat ini diusulkan)

:+1: @megawac, uniqBy.

Fwiw lodash akan menggunakan uniqBy sebagai bentuk terpisah dari _.uniq(array, iteratee) dan _.uniqWith sebagai formulir untuk memungkinkan penyesuaian komparator.

Ya, setelah dipikir-pikir uniqWith adalah nama yang lebih baik

haruskah saya menarik permintaan di Lodash dengan metode terpisah?
Saya pikir kedua proyek digabungkan, apakah saya salah?

@dperrymorrow

haruskah saya menarik permintaan di Lodash dengan metode terpisah?

Tidak perlu, mereka sudah ada di cabang master tepi lodash.

Saya pikir kedua proyek digabungkan, apakah saya salah?

Belum. Lodash v4 membuktikan beberapa ide penggabungan.

@jdalton Bisakah Anda menjelaskan lebih lanjut tentang implementasi _.uniqWith dengan iteratee lainnya.

@Pavnii
Tentu. Anda dapat memeriksa lodash/npm/_baseUniq .
Jika comparator dilewatkan, ia menggunakan arrayIncludesWith helper untuk melakukan pemeriksaan alih-alih arrayIncludes (Underscore's contains ).

@jdalton Itu membantu saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat