web-dev-qa-db-ja.com

Ruby Array#mapの `return`

Map関数内で何を返すかを決定したいメソッドがあります。これは変数を割り当てることで実行できることは承知していますが、これは私が実行できる方法です。

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

これは、returnが最初にヒットしたときにメソッドから返され、マップ関数ではなく、JavaScriptのマップ関数での戻り値の使用方法と同様に、期待どおりに機能しません。

希望する構文を実現する方法はありますか?または、これを変数に割り当てて、次のように最後にぶら下げておく必要がありますか?

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

変数は必要ありません。ブロックの戻り値は、その中で評価された最後の式の値です。この場合、ifです。

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

3項演算子の方が見栄えが良いと思います。もっと表現っぽい。

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

returnの使用を主張する場合は、ラムダを使用できます。ラムダでは、returnは通常のメソッドのように動作します。

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

ただし、このフォームはめったに見られません。コードが短い場合は、式として書き直すことができます。コードが長く、複数の出口点を必要とするほど複雑な場合は、おそらくそれを単純化してみてください。

21

セルジオの答えはとても良いですが、isreturnを希望どおりに機能させるキーワードnextがあることを指摘しておく価値があります。

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

これはnextのあまり良い使い方ではありません。セルジオが指摘したように、そこには何も必要ないからです。ただし、nextを使用すると、より簡潔に表現できます。

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

returnキーワードは、メソッド内でのみ使用できます(実際にはProcを含みます)。 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)

nextの代わりにreturnを使用できます。

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