¿Buscar el primer objeto?


¿Me falta algo en la documentación de la matriz? Tengo una matriz que contiene hasta un objeto que satisface un cierto criterio. Me gustaría encontrar eficientemente ese objeto. La mejor idea que tengo de los documentos es esta:

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

Pero estoy insatisfecho por dos razones: (1) que select me hizo recorrer todo el array, a pesar de que podríamos haber abandonado después del primer golpe, y (2) Necesitaba una línea de código (con una condición) para aplanar a los candidatos. Ambas operaciones son derrochadoras con conocimiento previo de que hay 0 o 1 objetos satisfactorios.

Lo que me gustaría es algo como:

array.find_first(block) -> responde nil o el primer objeto para el que el bloque se evalúa como verdadero, terminando el recorrido en ese objeto.

¿Debo escribir esto yo mismo? Todos esos otros grandes métodos en la matriz me hacen pensar que está allí y no lo estoy viendo.

Gracias de antemano, Dan

Author: marcgg, 2010-03-04

4 answers

O no entiendo tu pregunta, o Enumerable#find es lo que estabas buscando.

 154
Author: Mladen Jablanović,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-14 19:37:47

Use el método array detect si desea devolver el primer valor donde block devuelve true

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

OR

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

Si desea devolver todos los valores donde block devuelve true, use select

[1,2,3,11,34].select(&:even?)  #=> [2, 34]
 74
Author: Sandip Ransing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-17 10:14:51

Supongo que se acaba de perder el método find en los documentos:

my_array.find {|e| e.satisfies_condition? }
 13
Author: sepp2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-04 17:13:58

¿Necesita el objeto en sí o solo necesita saber si es un objeto que satisface. Si el primero entonces sí: use find:

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

De lo contrario puedes usar any?

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

Este último caerá con "verdadero" cuando encuentre uno que satisfaga la condición. El primero hará lo mismo, pero devolverá el objeto.

 11
Author: Taryn East,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-04 17:16:29