Agregasi menyimpulkan sekumpulan nilai menjadi satu hasil ringkas, dan Enumerable menyediakan metodenya dalam bentuk siap pakai. Metode reduce menggabungkan seluruh elemen menjadi satu nilai, tally menghitung frekuensi kemunculan, group_by mengelompokkan elemen menurut syarat, sedangkan sort_by mengurutkan menurut kunci pilihan. Topik ini membahas keempatnya menggunakan contoh catatan suhu sensor dan rekap peminjaman.
reduce untuk agregasi#
Metode reduce menggabungkan seluruh elemen menjadi satu nilai dengan membawa akumulasi, yaitu hasil sementara yang diperbarui pada setiap iterasi. Blok menerima dua argumen, yaitu akumulasi dan elemen yang sedang diproses, lalu baris terakhirnya menjadi nilai akumulasi yang baru. Nilai awal akumulasi diberikan sebagai argumen metode.
# Rekap catatan suhu sensor sepanjang hari.
bacaan = [22.5, 23.0, 24.5, 23.5, 22.0]
total = bacaan.reduce(0) { |akumulasi, suhu| akumulasi + suhu }
rata_rata = total / bacaan.length
tertinggi = bacaan.reduce { |a, b| a > b ? a : b }
p total
p rata_rata
p tertinggi115.5
23.1
24.5Perhitungan total berjalan lima iterasi, yaitu 0 + 22.5, lalu 22.5 + 23.0, dan seterusnya hingga seluruh bacaan habis. Pemanggilan kedua tidak memberi nilai awal, sehingga elemen pertama menjadi akumulasi awal dan blok hanya membandingkan dua suhu lalu menyimpan yang lebih tinggi. Untuk penjumlahan biasa, Enumerable juga menyediakan sum yang lebih ringkas, sedangkan reduce digunakan ketika penggabungannya lebih kompleks.
Bentuk tanpa nilai awal juga berguna untuk menyambung string, karena akumulasi awalnya otomatis berupa elemen pertama.
kata = ["api", "buku", "lampu"]
p kata.reduce { |gabungan, item| gabungan + "-" + item }"api-buku-lampu"tally untuk penghitungan#
Metode tally menghitung berapa kali setiap nilai muncul dan mengembalikan Hash dengan elemen sebagai kunci serta jumlah kemunculannya sebagai nilai. Metode ini menggantikan perulangan manual yang mengisi hash penghitung satu per satu.
pinjaman = %w[fisika fisika biologi fisika matematika biologi]
p pinjaman.tally{"fisika" => 3, "biologi" => 2, "matematika" => 1}Kunci keluarannya mengikuti urutan kemunculan pertama masing-masing nilai, yaitu fisika muncul lebih dulu pada data, lalu biologi, dan terakhir matematika. Hasilnya berupa Hash biasa, sehingga seluruh metode hash dapat digunakan padanya, misalnya keys atau values.
group_by untuk pengelompokan#
Metode group_by membagi elemen ke dalam beberapa kelompok menurut hasil blok dan mengembalikan Hash dengan hasil blok sebagai kunci serta array elemen sebagai nilainya. Blok yang sering digunakan adalah pertanyaan benar-salah, sehingga terbentuk dua kelompok bernama true dan false.
nilai = [80, 55, 90, 65, 75]
p nilai.group_by { |n| n >= 75 }{true => [80, 90, 75], false => [55, 65]}Urutan elemen di dalam setiap kelompok mengikuti urutan asalnya, sehingga anggota kelompok true terbaca [80, 90, 75] sebagaimana kemunculannya. Hasil blok tidak harus benar-salah, misalnya berupa huruf awal atau kategori, dan setiap hasil blok yang unik akan membentuk satu kunci kelompok baru.
sort_by untuk pengurutan#
Metode sort_by mengurutkan elemen menurut nilai yang dihitung blok untuk setiap elemen, bukan menurut elemennya sendiri. Blok menentukan kunci pengurutan, misalnya mengurutkan hash menurut nilainya dan bukan menurut kuncinya.
kota_suhu = { jakarta: 31, bandung: 24, semarang: 28 }
urut = kota_suhu.sort_by { |kota, derajat| derajat }
p urut
p urut.to_h[[:bandung, 24], [:semarang, 28], [:jakarta, 31]]
{bandung: 24, semarang: 28, jakarta: 31}Pengurutan atas hash menghasilkan array berisi pasangan, sehingga metode to_h diperlukan apabila bentuk hash ingin dipertahankan. Urutan menurun diperoleh dengan membalik tanda kunci pengurutan, misalnya mengurutkan rekap frekuensi dari yang paling sering.
pinjaman = %w[fisika fisika biologi fisika matematika biologi]
peringkat = pinjaman.tally.sort_by { |judul, jumlah| -jumlah }
p peringkat[["fisika", 3], ["biologi", 2], ["matematika", 1]]Rangkaian tally lalu sort_by membentuk peringkat yang terbaca sebagai satu kalimat, yaitu hitung frekuensinya, kemudian urutkan jumlahnya secara menurun.
Kesalahan umum#
Kesalahan pertama adalah blok reduce yang baris terakhirnya bukan akumulasi. Metode seperti puts mengembalikan nil, sehingga akumulasi berubah menjadi nil pada iterasi berikutnya dan perhitungan gagal.
# tidak-dijalankan
bacaan = [22.5, 23.0, 24.5]
rekap = bacaan.reduce(0) { |akumulasi, suhu| puts akumulasi + suhu }Iterasi pertama mencetak 22.5 lalu mengembalikan nil, sehingga iterasi kedua mencoba nil + 23.0 dan memunculkan NoMethodError.
Kesalahan kedua adalah menggunakan bentuk tanpa nilai awal untuk penggabungan yang mengubah tipe akumulasi. Bentuk ini bekerja selama tipe akumulasinya konsisten, tetapi gagal begitu blok mengembalikan tipe yang berbeda dari elemennya.
# tidak-dijalankan
kata = ["api", "buku", "lampu"]
panjang = kata.reduce { |a, b| a.length + b.length }Iterasi pertama menghasilkan bilangan 7 dari 3 + 4, sedangkan iterasi kedua memanggil length atas bilangan itu dan memunculkan NoMethodError. Perbaikannya adalah memberi nilai awal 0 sehingga akumulasi sejak awal berupa bilangan.
kata = ["api", "buku", "lampu"]
panjang = kata.reduce(0) { |total, item| total + item.length }
p panjang12Dengan nilai awal 0, akumulasi tetap berupa bilangan pada setiap iterasi, sehingga hasilnya 12 dan tidak bergantung pada tipe elemen pertama.
Ringkasan#
reducemembawa akumulasi melalui seluruh elemen, dan nilai awalnya menentukan tipe hasil untuk koleksi berukuran apa pun.tallymenghitung frekuensi kemunculan dan mengembalikan Hash dengan elemen sebagai kunci serta jumlah sebagai nilai.group_bymengelompokkan elemen menurut hasil blok ke dalam Hash berisi array.sort_bymengurutkan menurut kunci hasil blok, danto_hmengubah kembali array pasangan menjadi Hash.
Referensi#
- Enumerable#reduce — Ruby — Dokumentasi reduce beserta aturan nilai awal akumulasinya.
- Enumerable#tally — Ruby — Dokumentasi tally untuk penghitungan frekuensi kemunculan.
- Enumerable#group_by — Ruby — Dokumentasi group_by untuk pengelompokan menurut hasil blok.
- Enumerable#sort_by — Ruby — Dokumentasi sort_by untuk pengurutan menurut kunci pilihan.