Ruby Array trova il primo oggetto?


135

Mi manca qualcosa nella documentazione dell'array? Ho un array che contiene fino a un oggetto che soddisfa un determinato criterio. Vorrei trovare quell'oggetto in modo efficiente. L'idea migliore che ho dai documenti è questa:

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

Ma non sono soddisfatto per due motivi:

  1. Questo selectmi ha fatto attraversare l'intero array, anche se avremmo potuto salvare dopo il primo colpo.
  2. Avevo bisogno di una riga di codice (con una condizione) per appiattire i candidati.

Entrambe le operazioni sono dispendiose con la consapevolezza che ci sono 0 o 1 oggetti soddisfacenti.

Quello che mi piacerebbe è qualcosa di simile:

array.find_first(block)

che restituisce zero o il primo oggetto per il quale il blocco viene considerato vero, terminando l'attraversamento su quell'oggetto.

Devo scriverlo da solo? Tutti quegli altri grandi metodi in Array mi fanno pensare che sia lì e non lo vedo.

Risposte:


201

O non capisco la tua domanda, o Enumerable # find è la cosa che stavi cercando.


32
Nessun problema, trovo spesso fastidioso che la documentazione di Ruby non elenchi i metodi di tutte le classi e i moduli ereditati o inclusi.
Mladen Jablanović,

4
ulteriori informazioni: l' [1,2,3,5,2].find { |n| puts n; n == 2 } iterazione si interrompe quando trova il primo elemento corrispondente.
rajuGT

97

utilizzare il detectmetodo array se si desidera restituire il primo valore in cui il blocco restituisce true

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

OR

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

Se si desidera restituire tutti i valori in cui il blocco restituisce true, utilizzare select

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

5
.detectè esattamente ciò di cui ho bisogno. Ma allora che differenza fa .find?
Augustin Riedinger,

13
@AugustinRiedinger nessuna differenza, entrambi sono uguali. detectè solo un alias perfind ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find
Sandip Ransing

per un po 'di coerenza mi piace seguire The Ruby Style Guide , che preferisce trovare
Paul van Leeuwen,

20

Immagino ti sia appena perso il metodo find nei documenti:

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

8
O se ti piace giocare a golf,my_array.find(&:satisfies_condition?)
Andrew Grimm,

14

Avete bisogno l'oggetto stesso o avete solo bisogno di sapere se v'è un oggetto che soddisfa. Se il primo quindi sì: utilizzare trova:

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

altrimenti puoi usare any?

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

Quest'ultimo salverà con "vero" quando troverà uno che soddisfa la condizione. Il primo farà lo stesso, ma restituirà l'oggetto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.