Jika saya memiliki loop seperti
users.each do |u|
#some code
end
Di mana pengguna adalah hash dari beberapa pengguna. Apa logika kondisional termudah untuk dilihat jika Anda berada di pengguna terakhir dalam hash pengguna dan hanya ingin mengeksekusi kode tertentu untuk pengguna terakhir itu, jadi seperti
users.each do |u|
#code for everyone
#conditional code for last user
#code for the last user
end
end
ruby-on-rails
ruby
loops
each
Splashlin
sumber
sumber
each_with_index
ataulast
metode.Hash
bercampur di Enumerable, jadi memang adaeach_with_index
. Meskipun kunci hash tidak diurutkan, logika semacam ini selalu muncul saat merender tampilan, di mana item terakhir mungkin ditampilkan secara berbeda terlepas dari apakah itu benar-benar "terakhir" dalam arti data yang berarti.each_with_index
, maaf. Ya, saya dapat melihat bahwa itu akan muncul; hanya mencoba untuk memperjelas pertanyaannya. Secara pribadi jawaban terbaik bagi saya adalah penggunaan.last
tetapi itu tidak berlaku untuk hash hanya sebuah array.Jawaban:
users.each_with_index do |u, index| # some code if index == users.size - 1 # code for the last user end end
sumber
.last
luar loop.users.each_with_index do |(key, value), index| #your code end
Jika ini adalah situasi salah satu / atau, di mana Anda menerapkan beberapa kode ke semua kecuali pengguna terakhir dan kemudian beberapa kode unik hanya untuk pengguna terakhir, salah satu solusi lain mungkin lebih tepat.
Namun, Anda tampaknya menjalankan kode yang sama untuk semua pengguna, dan beberapa kode tambahan untuk pengguna terakhir. Jika demikian, ini tampaknya lebih benar, dan lebih jelas menyatakan maksud Anda:
users.each do |u| #code for everyone end users.last.do_stuff() # code for last user
sumber
.last
yang tidak ada hubungannya dengan perulangan..last
. Koleksi ini sudah dibuat instance-nya, itu hanya akses sederhana dari sebuah array. Sekalipun koleksi belum dimuat (seperti dalam, itu masih merupakan relasi ActiveRecord yang tidak terhidrasi)last
masih tidak pernah berulang untuk mendapatkan nilai terakhir, itu akan sangat tidak efisien. Ini hanya mengubah kueri SQL untuk mengembalikan catatan terakhir..each
Meskipun demikian, koleksi ini telah dimuat oleh , jadi tidak ada kerumitan yang lebih daripada jika Anda melakukannyax = [1,2,3]; x.last
.Menurut saya pendekatan terbaik adalah:
users.each do |u| #code for everyone if u.equal?(users.last) #code for the last user end end
sumber
u.equal?(users.last)
,equal?
metode membandingkan object_id, bukan nilai objek. Tetapi ini tidak akan bekerja dengan simbola dan angka.Apakah kamu sudah mencobanya
each_with_index
?users.each_with_index do |u, i| if users.size-1 == i #code for last items end end
sumber
h = { :a => :aa, :b => :bb } h.each_with_index do |(k,v), i| puts ' Put last element logic here' if i == h.size - 1 end
sumber
Terkadang saya merasa lebih baik untuk memisahkan logika menjadi dua bagian, satu untuk semua pengguna dan satu lagi untuk yang terakhir. Jadi saya akan melakukan sesuatu seperti ini:
users[0...-1].each do |user| method_for_all_users user end method_for_all_users users.last method_for_last_user users.last
sumber
Anda dapat menggunakan pendekatan @ meager juga untuk situasi salah satu / atau, di mana Anda menerapkan beberapa kode ke semua kecuali pengguna terakhir dan kemudian beberapa kode unik hanya untuk pengguna terakhir.
users[0..-2].each do |u| #code for everyone except the last one, if the array size is 1 it gets never executed end users.last.do_stuff() # code for last user
Dengan cara ini Anda tidak perlu bersyarat!
sumber
users[0..-2]
benar, sebagaimana adanyausers[0...-1]
. Perhatikan perbedaan operator..
vs...
, lihat stackoverflow.com/a/9690992/67834Solusi lain adalah menyelamatkan dari StopIteration:
user_list = users.each begin while true do user = user_list.next user.do_something end rescue StopIteration user.do_something end
sumber
StopIteration
dirancang untuk alasan yang tepat dalam menangani keluar loop. Dari buku Matz: "Ini mungkin tampak tidak biasa — pengecualian dimunculkan untuk kondisi penghentian yang diharapkan daripada kejadian yang tidak terduga dan luar biasa. (StopIteration
Adalah keturunan dariStandardError
danIndexError
; perhatikan bahwa ini adalah satu-satunya kelas pengecualian yang tidak memiliki kata "Error" dalam namanya.) Ruby mengikuti Python dalam teknik iterasi eksternal ini. (Selengkapnya ...)next
untuk nilai akhir iterasi khusus, dan tidak perlu memanggil semacamnext?
predikat sebelum meneleponnext
. "loop do
memiliki implisitrescue
ketika menghadapi aStopIteration
; ini secara khusus digunakan saat melakukan iterasiEnumerator
objek secara eksternal .loop do; my_enum.next; end
akan mengulangmy_enum
dan keluar pada akhirnya; tidak perlu dimasukkan kerescue StopIteration
sana. (Anda harus melakukannya jika Anda menggunakanwhile
atauuntil
.)Tidak ada metode hash terakhir untuk beberapa versi ruby
h = { :a => :aa, :b => :bb } last_key = h.keys.last h.each do |k,v| puts "Put last key #{k} and last value #{v}" if last_key == k end
sumber
last
, rangkaian kunci tidak akan diurutkan, jadi jawaban ini akan mengembalikan hasil yang salah / acak.