Array Ruby find_first objek?

135

Apakah saya kehilangan sesuatu dalam dokumentasi Array? Saya memiliki array yang berisi hingga satu objek yang memenuhi kriteria tertentu. Saya ingin menemukan objek itu dengan efisien. Ide terbaik yang saya miliki dari dokumen adalah:

candidates = my_array.select { |e| e.satisfies_condition? }
found_it = candidates.first if !candidates.empty?

Tetapi saya tidak puas karena dua alasan:

  1. Itu selectmembuat saya melintasi seluruh jajaran, meskipun kami bisa menyelamatkan setelah hit pertama.
  2. Saya membutuhkan sebaris kode (dengan syarat) untuk meratakan kandidat.

Kedua operasi tersebut boros dengan pengetahuan sebelumnya bahwa ada 0 atau 1 objek yang memuaskan.

Yang saya sukai adalah sesuatu seperti:

array.find_first(block)

yang mengembalikan nil atau objek pertama yang bloknya bernilai true, mengakhiri traversal pada objek itu.

Haruskah saya menulis ini sendiri? Semua metode hebat lainnya di Array membuat saya berpikir ada di sana dan saya tidak melihatnya.

Manusia Timah
sumber

Jawaban:

201

Entah saya tidak mengerti pertanyaan Anda, atau Enumerable # find adalah hal yang Anda cari.

Mladen Jablanović
sumber
32
Tidak masalah, saya juga sering merasa kesal karena dokumentasi ruby ​​tidak mencantumkan metode semua kelas dan modul yang diwarisi atau disertakan.
Mladen Jablanović
4
info lebih lanjut: [1,2,3,5,2].find { |n| puts n; n == 2 } iterasi berhenti setelah menemukan elemen pertama yang cocok.
rajuGT
97

gunakan detectmetode array jika Anda ingin mengembalikan nilai pertama di mana blok mengembalikan true

[1,2,3,11,34].detect(&:even?) #=> 2

OR

[1,2,3,11,34].detect{|i| i.even?} #=> 2

Jika Anda ingin mengembalikan semua nilai di mana blok mengembalikan true lalu gunakan select

[1,2,3,11,34].select(&:even?)  #=> [2, 34]
Sandip Ransing
sumber
5
.detectpersis apa yang saya butuhkan. Tapi apa bedanya dengan .finditu?
Augustin Riedinger
13
@AugustinRiedinger tidak ada perbedaan, keduanya sama. detecthanyalah alias untuk find ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find
Sandip
untuk beberapa konsistensi, saya ingin mengikuti The Ruby Style Guide , yang lebih disukai
Paul van Leeuwen
20

Kira Anda baru saja melewatkan metode pencarian di dokumen:

my_array.find {|e| e.satisfies_condition? }
sepp2k
sumber
8
Atau jika Anda suka golf code,my_array.find(&:satisfies_condition?)
Andrew Grimm
14

Apakah Anda memerlukan objek itu sendiri atau apakah Anda hanya perlu tahu apakah ada adalah sebuah objek yang memenuhi. Jika yang pertama maka ya: gunakan temukan:

found_object = my_array.find { |e| e.satisfies_condition? }

jika tidak, Anda dapat menggunakan any?

found_it = my_array.any?  { |e| e.satisfies_condition? }

Yang terakhir akan menjamin dengan "benar" ketika menemukan yang memenuhi syarat. Yang pertama akan melakukan hal yang sama, tetapi mengembalikan objek.

Taryn East
sumber