在Ruby中使用“Yield”和多个方法

时间:2015-02-22 02:13:18

标签: ruby

尝试定义一个new_map函数,该函数将数组作为参数并返回根据以下RSpec修改的新数组:

describe "new_map" do
  it "should not call map or map!" do
    a = [1, 2, 3]
    a.stub(:map) { '' }
    a.stub(:map!) { '' }

    expect( new_map(a) { |i| i + 1 } ).to eq([2, 3, 4])
  end

  it "should map any object" do
    a = [1, "two", :three]
    expect( new_map(a) { |i| i.class } ).to eq([Fixnum, String, Symbol])
  end
end

我的代码独立工作,但不能同时满足两个RSpec。我知道我有两个同名的方法(new_map),但我不知道如何将两者结合起来。

def new_map(array)
  new_array = []
  array.each do |item|
    new_array << item +1
  end
  new_array
end

def new_map(array)
  new_array = []
  array.map do |item|
    new_array << item.class
  end
  new_array
end

感谢您帮助初学者。

1 个答案:

答案 0 :(得分:3)

这应该有效:

def new_map(array)
    new_array = []
    array.each do |item|
        new_array << yield(item)
    end
    new_array
end

编辑: 顺便说一句,引起麻烦的是你想要映射列表项的特定方式包含在方法中。我认为改变其中一个的名字是让它像这样工作的唯一方法。

你也在调用new_map()时给出了块,但是没有在new_map()中使用它们。

在函数内部,关键字&#39; yield&#39;允许您调用传递给您的函数的块,并提供任何值(如果有)。所以正确的想法是将块内的确切映射内容分开,并在函数内部迭代地使用列表中的每个元素调用它,然后将结果返回到要返回的数组。

EDIT2: 我还想补充一点,如果你想要一个只有特定映射方法的特殊map函数,我建议使用一个用proc创建的可重用块。示例:

array = [1,2,3]

# Create the mapping you want.
mapping = proc do |item|
    item + 1
end

# Now use that proc in a map function.
new_map(array, &mapping)
# => [2,3,4]