Objet find_first Ruby Array?


135

Est-ce que je manque quelque chose dans la documentation Array? J'ai un tableau qui contient jusqu'à un objet satisfaisant à un certain critère. J'aimerais trouver efficacement cet objet. La meilleure idée que j'ai de la documentation est la suivante:

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

Mais je ne suis pas satisfait pour deux raisons:

  1. Cela selectm'a fait parcourir tout le tableau, même si nous aurions pu renflouer après le premier coup.
  2. J'avais besoin d'une ligne de code (avec une condition) pour aplatir les candidats.

Les deux opérations sont inutiles avec la prescience qu'il y a 0 ou 1 objet satisfaisant.

Ce que je voudrais, c'est quelque chose comme:

array.find_first(block)

qui renvoie nil ou le premier objet pour lequel le bloc est évalué à vrai, mettant fin au parcours à cet objet.

Dois-je écrire cela moi-même? Toutes ces autres méthodes géniales dans Array me font penser que c'est là et je ne le vois tout simplement pas.

Réponses:


201

Soit je ne comprends pas votre question, soit Enumerable # find est ce que vous cherchiez.


32
Pas de problème, je trouve aussi souvent ennuyeux que la documentation ruby ​​ne répertorie pas les méthodes de toutes les classes et modules hérités ou inclus.
Mladen Jablanović

4
plus d'infos: l' [1,2,3,5,2].find { |n| puts n; n == 2 } itération s'arrête une fois qu'il trouve le premier élément auquel il correspond.
rajuGT

97

utilisez la detectméthode de tableau si vous voulez retourner la première valeur où le bloc retourne vrai

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

OR

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

Si vous souhaitez renvoyer toutes les valeurs où block retourne true, utilisez select

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

5
.detectest exactement ce dont j'ai besoin. Mais quelle est la différence avec .findalors?
Augustin Riedinger le

13
@AugustinRiedinger aucune différence, les deux sont identiques. detectest juste un alias de find ruby-doc.org/core-2.1.2/Enumerable.html#method-i-find
Sandip Ransing

pour un peu de cohérence, j'aime suivre The Ruby Style Guide , qui favorise la recherche
Paul van Leeuwen

20

Je suppose que vous venez de manquer la méthode de recherche dans la documentation:

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

8
Ou si vous aimez le golf codé,my_array.find(&:satisfies_condition?)
Andrew Grimm

14

Est - ce que vous avez besoin de l'objet lui - même ou avez - vous juste besoin de savoir s'il est un objet qui satisfait. Si le premier alors oui: utilisez find:

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

sinon vous pouvez utiliser any?

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

Ce dernier renoncera à "vrai" lorsqu'il en trouvera un qui satisfait à la condition. Le premier fera de même, mais retournera l'objet.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.