Lima cara menarik untuk menggunakan Array.reduce () (dan satu cara membosankan)

Halo, Habr! Saya mempersembahkan kepada Anda terjemahan artikel "Lima Cara Menarik untuk Menggunakan Array.reduce () (Dan Satu Cara Membosankan)" oleh Chris Ferdinandi.


Dari semua metode modern untuk bekerja dengan array, yang paling sulit dari semua yang harus saya gunakan adalah Array.reduce ().


Pada pandangan pertama, ini tampaknya menjadi metode sederhana dan membosankan yang tidak banyak berpengaruh. Namun, meskipun tampilannya sederhana, Array.reduce () adalah tambahan yang kuat dan fleksibel untuk set alat pengembang Anda.


Hari ini, mari kita lihat beberapa hal menarik yang dapat Anda lakukan dengan Array.reduce ().


Bagaimana Array.reduce () Bekerja


Sebagian besar metode array modern mengembalikan array baru. Metode Array.reduce () sedikit lebih fleksibel. Dia bisa mengembalikan apa saja. Tujuannya adalah untuk mengambil array dan mengompres isinya menjadi satu nilai.


Nilai ini bisa berupa angka, string, atau bahkan objek atau array baru. Ini adalah bagian yang selalu membingungkan saya - saya tidak mengerti betapa fleksibelnya itu!


Sintaks


Array.reduce () mengambil dua argumen: metode panggilan balik, yang dijalankan untuk meluncurkan setiap elemen dalam array, dan nilai awal initialValue.


Callback juga mengambil dua argumen: akumulator, yang merupakan nilai gabungan saat ini, dan item saat ini dalam loop CurrentValue. Semua yang Anda kembalikan digunakan sebagai akumulator untuk elemen berikutnya dalam loop. Loop pertama menggunakan nilai awal sebagai gantinya.


var myNewArray = [].reduce(function (accumulator, current) { return accumulator;}, starting); }, starting); 

Mari kita lihat beberapa contoh.


 var myNewArray = [].reduce(function (accumulator, current) { return accumulator;}, starting); 

1. Penjumlahan angka


Misalkan Anda memiliki array angka yang ingin Anda tambahkan bersama. Menggunakan Array.forEach (), kita dapat melakukan sesuatu seperti ini:


 var total = 0; [1, 2, 3].forEach(function (num) { total += num; }); 

Ini adalah contoh klise untuk menggunakan Array.reduce (). Kata "akumulator" membingungkan, jadi dalam contoh ini kita akan menyebutnya "jumlah" karena itu adalah apa yang secara inheren.


 var total = [1, 2, 3].reduce(function (sum, current) { return sum + current; }, 0);    0    . 

Dalam panggilan balik, kami menambahkan nilai saat ini ke jumlah yang memiliki nilai awal 0 pada siklus pertama, lalu 1 (nilai awal 0 ditambah nilai elemen 1), lalu 3 (nilai total 1 ditambah nilai elemen 2) dan seterusnya.
Sebuah contoh


2. Alternatif untuk menggabungkan metode array Array.map () dan Array.filter () dalam satu langkah


Bayangkan ada banyak penyihir di Hogwarts.


 var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' }]; 

Kami ingin membuat array baru yang hanya akan berisi nama-nama master dari Hufflepuff. Salah satu cara untuk melakukan ini adalah menggunakan metode Array.filter () untuk mendapatkan kembali hanya penyihir yang memiliki properti Hufflepuff di rumah. Kemudian kita menggunakan metode Array.map () untuk membuat array baru yang hanya berisi properti nama untuk master yang tersisa.


 //      var hufflepuff = wizards.filter(function (wizard) { return wizard.house === 'Hufflepuff'; }).map(function (wizard) { return wizard.name; }); 

Menggunakan metode Array.reduce (), Anda bisa mendapatkan array yang sama dalam satu pass, yang akan meningkatkan kinerja kami. Kami melewati array kosong ([]) sebagai nilai awal. Di setiap pass, kami memeriksa untuk melihat apakah wizard.house adalah Hufflepuff. Jika demikian, kirim ke newArr (akumulator kami dalam contoh ini). Jika tidak, jangan lakukan apa pun.


Bagaimanapun, kembalikan newArr untuk mendapatkan akumulator di pass berikutnya.


 //      var hufflepuff = wizards.reduce(function (newArr, wizard) { if (wizard.house === 'Hufflepuff') { newArr.push(wizard.name); } return newArr; }, []); 

Sebuah contoh


3.Buat markup dari array


Bagaimana jika, alih-alih membuat array nama, kami ingin membuat daftar master yang tidak terurut di Hufflepuff? Alih-alih array kosong di Array.reduce () sebagai nilai awal kami, sampaikan string kosong ('') dan beri nama html.


Jika wizard.house sama dengan Hufflepuff, kami menggabungkan string html kami dengan wizard.name yang dibungkus dengan elemen daftar pembuka dan penutup (li). Kemudian kembalikan HTML sebagai akumulator di loop berikutnya.


 //      var hufflepuffList = wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, ''); 

Tambahkan membuka dan menutup item daftar yang tidak berurutan sebelum dan sesudah Array.reduce (). Sekarang Anda siap untuk menambahkan markup ke DOM.


 //      var hufflepuffList = '<ul>' + wizards.reduce(function (html, wizard) { if (wizard.house === 'Hufflepuff') { html += '<li>' + wizard.name + '</li>'; } return html; }, '') + '</ul>'; 

Sebuah contoh


4. Mengelompokkan elemen serupa ke dalam array


Pustaka lodash memiliki metode groupBy () yang mengambil kumpulan elemen sebagai array dan mengelompokkannya menjadi objek berdasarkan beberapa kriteria.


Katakanlah kita membutuhkan sejumlah angka.


Jika kita ingin mengelompokkan semua elemen menjadi angka dengan nilai integernya, maka ini harus dilakukan dengan menggunakan lodash.


 var numbers = [6.1, 4.2, 6.3]; // returns {'4': [4.2], '6': [6.1, 6.3]} _.groupBy(numbers, Math.floor); 

Jika ada susunan kata, dan Anda perlu mengelompokkan elemen dalam kata berdasarkan panjangnya, kami akan melakukannya.


 var words = ['one', 'two', 'three']; // returns {'3': ['one', 'two'], '5': ['three']} _.groupBy(words, 'length'); 

Membuat fungsi groupBy () menggunakan Array.reduce ()


Anda dapat membuat ulang fungsionalitas yang sama menggunakan metode Array.reduce ().


Kami membuat fungsi bantu groupBy (), yang mengambil array dan kriteria untuk menyortir sebagai argumen. Di dalam groupBy (), kita akan menjalankan Array.reduce () untuk array kita, melewati objek kosong ({}) sebagai titik awal dan mengembalikan hasilnya.


 var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { // Some code will go here... }, {}); }; 

Di dalam Array.reduce (), kami memanggil fungsi callback untuk memeriksa apakah kriteria adalah fungsi yang diterapkan pada elemen atau properti elemen. Kemudian kita mendapatkan nilainya dari elemen saat ini.


Jika objek belum memiliki properti dengan nilai ini, buat [properti] dan tetapkan array kosong sebagai nilainya. Akhirnya, tambahkan elemen ke properti ini dan kembalikan objek sebagai akumulator untuk siklus berikutnya.


 var groupBy = function (arr, criteria) { return arr.reduce(function (obj, item) { //   ,        //  var key = typeof criteria === 'function' ? criteria(item) : item[criteria]; //    ,  . if (!obj.hasOwnProperty(key)) { obj[key] = []; } //     obj[key].push(item); //      return obj; }, {});}; 

Peragaan fungsi pembantu yang lengkap.


Terima kasih khusus kepada Tom Bremer atas bantuannya. Fungsi pembantu ini dan banyak lagi dapat ditemukan di Vanilla JS Toolkit .


5. Menggabungkan data dari dua sumber ke dalam array


Ingat daftar penyihir kami.


 var wizards = [ { name: 'Harry Potter', house: 'Gryfindor' }, { name: 'Cedric Diggory', house: 'Hufflepuff' }, { name: 'Tonks', house: 'Hufflepuff' }, { name: 'Ronald Weasley', house: 'Gryfindor' }, { name: 'Hermione Granger', house: 'Gryfindor' }]; 

Bagaimana jika ada set data yang berbeda - objek dengan rumah dan poin yang diperoleh masing-masing pesulap.


 var points = { HarryPotter: 500, CedricDiggory: 750, RonaldWeasley: 100, HermioneGranger: 1270 }; 

Bayangkan kita ingin menggabungkan kedua set data menjadi satu array dengan jumlah poin yang ditambahkan ke data masing-masing wizard dalam array wizards. Bagaimana cara melakukannya?


Metode Array.reduce () sangat cocok untuk ini!


 var wizardsWithPoints = wizards.reduce(function (arr, wizard) { //     points,     // var key = wizard.name.replace(' ', ' '); //     ,  , //   0. if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } //   wizard   . arr.push(wizard); //  . return arr; }, []); 

Contoh menggabungkan data dari dua sumber ke dalam array .


6. Menggabungkan data dari dua sumber menjadi suatu objek


Bagaimana jika sebaliknya diperlukan untuk menggabungkan dua sumber data menjadi objek di mana nama masing-masing penyihir adalah kuncinya, dan rumah dan kacamata mereka adalah properti? Sekali lagi, metode Array.reduce () sangat cocok untuk ini.


 var wizardsAsAnObject = wizards.reduce(function (obj, wizard) { //      points,     // var key = wizard.name.replace(' ', ' '); //     ,  , //   0. if (points[key]) { wizard.points = points[key]; } else { wizard.points = 0; } //   name delete wizard.name; //   wizard    obj[key] = wizard; //   return obj; }, {}); 

Contoh menggabungkan data dari dua sumber menjadi objek .


Haruskah saya menggunakan Array.reduce ()?


Metode Array.reduce () telah berevolusi dari tidak berarti menjadi metode JavaScript favorit saya. Jadi layakkah menggunakannya? Dan kapan?


Metode Array.reduce () memiliki dukungan browser yang fantastis. Ini bekerja di semua browser modern dan di IE9. Sudah lama didukung oleh peramban seluler. Jika Anda membutuhkan lebih banyak, Anda dapat menambahkan polyfill untuk mengembalikan dukungan di IE6.


Masalah yang paling serius mungkin adalah bahwa Array.reduce () membingungkan bagi orang yang belum pernah menemukannya [metode] sebelumnya. Kombinasi metode Array.filter () dengan Array.map () lebih lambat dan melibatkan langkah-langkah tambahan, tetapi lebih mudah dibaca. Nama-nama metode menunjukkan apa yang harus mereka lakukan.


Seperti yang telah disebutkan, metode Array.reduce (), secara umum, menyederhanakan hal-hal yang lebih kompleks. Contoh yang baik adalah fungsi helper groupBy ().


Pada akhirnya, ini adalah alat lain untuk toolkit Anda. Alat yang, jika digunakan dengan benar, dapat memberikan kekuatan super.


Tentang penulis


Chris Ferdinandi membantu orang belajar JavaScript vanila. Dia percaya bahwa ada cara yang lebih sederhana dan lebih dapat diandalkan untuk melakukan hal-hal untuk Internet.


Chris adalah penulis seri Panduan Saku Vanilla JS , pencipta kurikulum Akademi Vanilla JS , dan presenter Vanilla JS Podcast . Buletin penasihat pengembangnya dibaca oleh ribuan pengembang setiap hari kerja.


Dia melatih pengembang di organisasi seperti Chobani dan Boston Globe, dan plugin JavaScript-nya digunakan oleh Apple dan Harvard Business School. Chris Coyer, pendiri CSS-Tricks dan CodePen, menggambarkan karyanya sebagai "kutipan tanpa henti."


Chris menyukai bajak laut, anak anjing dan film Pixar, dan juga tinggal di dekat peternakan kuda di pedesaan Massachusetts. Dia memimpin Go Make Things dengan anak anjing Bailey.

Source: https://habr.com/ru/post/id483182/


All Articles