Bagaimana mendapatkan rata-rata dari array?
Jika saya memiliki array:
[0,4,8,2,5,0,2,6]
Rata-rata akan memberi saya 3,375.
ruby-on-rails
ruby
Dotty
sumber
sumber
Jawaban:
Coba ini:
Perhatikan
.to_f
, yang Anda inginkan untuk menghindari masalah dari divisi integer. Anda juga dapat melakukan:Anda dapat mendefinisikannya sebagai bagian dari
Array
apa yang disarankan komentator lain, tetapi Anda harus menghindari pembagian integer atau hasil Anda akan salah. Juga, ini umumnya tidak berlaku untuk setiap jenis elemen yang mungkin (jelas, rata-rata hanya masuk akal untuk hal-hal yang dapat dirata-ratakan). Tetapi jika Anda ingin pergi ke rute itu, gunakan ini:Jika Anda belum pernah melihat
inject
sebelumnya, itu tidak ajaib seperti yang mungkin muncul. Itu berulang atas setiap elemen dan kemudian menerapkan nilai akumulator untuknya. Akumulator kemudian diserahkan ke elemen berikutnya. Dalam hal ini, akumulator kami hanyalah bilangan bulat yang mencerminkan jumlah semua elemen sebelumnya.Sunting: Komentator Dave Ray mengusulkan perbaikan yang bagus.
Sunting: Proposal komentator Glenn Jackman, menggunakan
arr.inject(:+).to_f
, juga bagus tapi mungkin agak terlalu pintar jika Anda tidak tahu apa yang terjadi. Itu:+
adalah simbol; ketika melewati untuk menyuntikkan, itu berlaku metode yang dinamai oleh simbol (dalam hal ini, operasi penambahan) untuk setiap elemen terhadap nilai akumulator.sumber
arr.inject(0.0) { |sum,el| sum + el } / arr.size
.inject
antarmuka, yang disebutkan dalam dokumentasi. Theto_proc
operator adalah&
.Array#inject
berlebihan di sini. Gunakan saja#sum
. Misalnyaarr.sum.to_f / arr.size
Versi ini yang tidak digunakan
instance_eval
adalah:sumber
instance_eval
memungkinkan Anda menjalankan kode sementara hanya menentukana
sekali, sehingga dapat dirantai dengan perintah lain. Yaiturandom_average = Array.new(10) { rand(10) }.instance_eval { reduce(:+) / size.to_f }
alih-alihrandom = Array.new(10) { rand(10) }; random_average = random.reduce(:+) / random.size
self
dalam blok itu, Anda akan mengalami masalah.)instance_eval
Lebih untuk metaprogramming atau DSL.Saya percaya jawaban yang paling sederhana adalah
sumber
reduce
adalah metodeEnumerable
mixin yang digunakan olehArray
. Dan terlepas dari namanya, saya setuju dengan @ ShuWu ... kecuali jika Anda menggunakan Rails yang mengimplementasikansum
.Saya berharap untuk Matematika. Rata-rata (nilai), tetapi tidak beruntung.
sumber
sum
metode, jadi ini tampaknya jawaban yang benar setelah 6 tahun, layak untuk penghargaan Nostradamus.Versi Ruby> = 2.4 memiliki metode # jumlah Enumerable .
Dan untuk mendapatkan floating point rata-rata, Anda dapat menggunakan Integer # fdiv
Untuk versi yang lebih lama:
sumber
Beberapa pembandingan solusi teratas (dalam urutan yang paling efisien):
Array Besar:
Array Kecil:
sumber
sumber
nil
daripada 0?Biarkan saya membawa sesuatu ke dalam kompetisi yang memecahkan masalah divisi dengan nol:
Namun saya harus mengakui bahwa "coba" adalah penolong Rails. Tetapi Anda dapat dengan mudah menyelesaikan ini:
BTW: Saya pikir benar bahwa rata-rata daftar kosong adalah nol. Rata-rata tidak ada apa-apa, bukan 0. Jadi itulah perilaku yang diharapkan. Namun, jika Anda mengubah ke:
hasil untuk Array kosong tidak akan menjadi pengecualian seperti yang saya harapkan tetapi mengembalikan NaN ... Saya belum pernah melihat itu sebelumnya di Ruby. ;-) Tampaknya menjadi perilaku khusus kelas Float ...
sumber
apa yang saya tidak suka tentang solusi yang diterima
adalah bahwa itu tidak benar-benar berfungsi secara murni fungsional. kita membutuhkan variabel arr untuk menghitung arr.size di akhir.
untuk menyelesaikan ini murni secara fungsional kita perlu melacak dua nilai: jumlah semua elemen, dan jumlah elemen.
Santhosh meningkatkan solusi ini: alih-alih argumen r menjadi array, kita bisa menggunakan destrrukturisasi untuk segera mengambilnya menjadi dua variabel
jika Anda ingin melihat cara kerjanya, tambahkan beberapa put:
Kita juga bisa menggunakan struct alih-alih array untuk mengandung jumlah dan penghitungan, tetapi kemudian kita harus mendeklarasikan struct terlebih dahulu:
sumber
end.method
digunakan di ruby, terima kasih untuk ini!arr.inject([0.0,0]) { |(sum, size), el| [ sum + el, size + 1 ] }.inject(:/)
Untuk hiburan publik, solusi lain:
sumber
Tidak ada ruby pada pc ini, tetapi sesuatu sejauh ini harus bekerja:
sumber
Menambahkan
Array#average
.Saya melakukan hal yang sama cukup sering sehingga saya pikir lebih baik hanya memperpanjang
Array
kelas dengan sederhanaaverage
metode . Ini tidak berfungsi untuk apa pun selain array angka seperti Integer atau Mengapung atau Desimal tetapi berguna ketika Anda menggunakannya dengan benar.Saya menggunakan Ruby on Rails jadi saya menempatkan ini di
config/initializers/array.rb
tetapi Anda dapat menempatkannya di mana saja yang termasuk dalam boot, dll.config/initializers/array.rb
sumber
sumber
Memecahkan pembagian dengan nol, pembagian integer dan mudah dibaca. Dapat dengan mudah dimodifikasi jika Anda memilih untuk mengembalikan array kosong 0.
Saya suka varian ini juga, tetapi sedikit lebih bertele-tele.
sumber
sumber
Metode ini dapat membantu.
sumber
Tanpa harus mengulang array (mis. Sempurna untuk satu-liner):
sumber
Pendek tapi menggunakan variabel instan
sumber
a_size = nil; [1,2].tap { |a| a_size = a.size }.inject(:+).to_f/a_size
daripada membuat variabel instan.Anda dapat mencoba sesuatu seperti berikut ini:
sumber