Ruby:如何从Ruby返回单个值形式的每个方法

时间:2018-07-13 16:42:55

标签: ruby

我有下面的代码,该代码在方法末尾返回哈希值。我想做的是返回相同的响应,而无需在方法开始时声明response = {}。如何在红宝石中做到这一点?

def test 
response = {}
    objects.each do |object|
       response = object.fetch(55)
        break unless response.nil?
    end
   response
end    

5 个答案:

答案 0 :(得分:3)

您要返回fetch(55)的第一个结果吗?我会这样写下来

def test
  objects.lazy.map{|o| o.fetch(55)}.reject(&:nil?).first
end

答案 1 :(得分:2)

如果为给定数组的每个元素(大概是哈希)获取值很便宜,则可以编写以下内容。

def test1(arr)
  arr.find { |h| h[55] }&.[](55)
end

否则我会建议

def test2(arr)
  v = nil 
  arr.find { |h| v = h[55] } && v
end    

即使它不符合您的要求。 &首先是safe navigation operator,它在Ruby v2.3中首次亮相。 “便宜”是指不需要大量计算来确定键的值(例如,将pi计算为一百万个数字)。参见Hash#[]

假设

a1 = [{ 9=>'cat', 14=>'dog', 12=>'pig' }, { 9=>'cat', 55=>'dog', 12=>'pig' }]
a2 = [{ 9=>'cat', 14=>'dog', 12=>'pig' }, { 9=>'cat', 12=>'dog', 12=>'pig' }]

然后

test1(a1)
  #=> 'dog'
test1(a2)
  #=> nil

test2(a1)
  #=> 'dog'
test2(a2)
  #=> nil

如评论中所指出,以下是test1的变体。

def test1(arr)
  arr.find(->{{}}) { |h| h[55] }[55]
end

请参见Enumerable#find,特别是,如果没有找到匹配项,并且find包含一个对call进行响应的参数(即proc或方法),则将调用该参数并返回结果由find返回。 (要使用方法而不是proc:def m() {} end; arr.find(method(:m)) { |h| h[55] }[55]。)

答案 2 :(得分:1)

为什么return不在区块中?

def test 
  objects.find do |object|
     response = object.fetch(55)
     return response if response
  end
end

请注意,此 only 仅适用于方法。例如,如果您在irb中尝试此操作,则会收到LocalJumpError。

如果您只想从块中获取值而不实际从方法中返回,请使用break

def test 
  response = objects.find do |object|
     response = object.fetch(55)
     break response if response
  end
end

答案 3 :(得分:0)

Ruby自动返回放置在最后一行的值,因此您可以使用该逻辑c

答案 4 :(得分:0)

如果您只想在集合中查找与条件匹配的第一个实例,那么ruby有一个惯用的解决方案:#detect

object = [{1 => true}, {2 => true}, {55 => 'foo'}, {55 => 'bar'}]
object.detect { |o| o.fetch(55) { false } } #=> {55=>"foo"}