web-dev-qa-db-fra.com

`return` dans Ruby Array # map

J'ai une méthode où je voudrais décider quoi retourner dans une fonction de carte. Je suis conscient que cela peut être fait en affectant une variable, mais c'est ainsi que j'ai pensé que je pouvais le faire;

def some_method(array)
    array.map do |x|
      if x > 10
         return x+1 #or whatever
      else
         return x-1
      end
    end
end

Cela ne fonctionne pas comme je m'y attendais car la première fois que return est frappé, il revient de la méthode et non dans la fonction map, similaire à la façon dont le retour est utilisé dans la fonction map de javascript.

Existe-t-il un moyen d'atteindre la syntaxe souhaitée? Ou dois-je attribuer cela à une variable et le laisser suspendu à la fin comme ceci:

def some_method(array)
    array.map do |x|
      returnme = x-1
      if x > 10
         returnme = x+1 #or whatever
      end
      returnme
    end
end
25
Automatico

Vous n'avez pas besoin de la variable. La valeur de retour du bloc est la valeur de la dernière expression qui y est évaluée. Dans ce cas, le if.

def some_method(array)
    array.map do |x|
      if x > 10
         x+1
      else
         x-1
      end
    end
end

L'opérateur ternaire serait plus joli, je pense. Plus d'expression-ish.

def some_method(array)
  array.map do |x|
    (x > 10) ? x+1 : x-1
  end
end

Si vous insistez pour utiliser return, vous pouvez alors utiliser lambdas. Dans lambdas, return se comporte comme dans les méthodes normales.

def some_method(array)
  logic = ->(x) {
    if x > 10
      return x + 1
    else
      return x - 1
    end
  }
  array.map(&logic)
end

Cette forme est cependant rarement vue. Si votre code est court, il peut sûrement être réécrit sous forme d'expressions. Si votre code est suffisamment long et compliqué pour justifier plusieurs points de sortie, vous devriez probablement essayer de le simplifier.

21
Sergio Tulentsev

La réponse de Sergio est très bonne, mais il convient de souligner qu'il y a is un mot clé qui fonctionne comme vous vouliez que return fonctionne: next.

array.map do |x|
  if x > 10
    next x + 1
  else
    next x - 1
  end
end

Ce n'est pas une très bonne utilisation de next car, comme l'a souligné Sergio, vous n'avez besoin de rien. Cependant, vous pouvez utiliser next pour l'exprimer plus succinctement:

array.map do |x|
  next x + 1 if x > 10
  x - 1
end
51
Jordan Running

Le mot clé return ne peut être utilisé que dans une méthode (incluant en fait Proc). Cela augmentera le LocalJumpError

irb(main):123:0> array = [1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15]
irb(main):124:0> array.map { |n| return n }
Traceback (most recent call last):
        3: from (irb):124
        2: from (irb):124:in `map'
        1: from (irb):124:in `block in irb_binding'
LocalJumpError (unexpected return)

Vous pouvez utiliser next au lieu de return.

irb(main):126:0> array.map { |n| next n }
=> [1, 2, 3, 4, 5, 8, 9, 10, 11, 14, 15]
0
TorvaldsDB