红宝石块(收益率)

时间:2015-05-08 20:16:30

标签: ruby-on-rails ruby rspec

我刚刚开始使用Ruby,我在Bloc的课程中已经很方便但是现在我被困在关于产量和块的练习上(我发现这是迄今为止最难掌握的概念)当谈到学习红宝石时。)

以下是纯文本格式文本中所需的规范:

  • 定义new_map方法
  • 它应该以数组作为参数,并返回根据作为块传入的指令修改的新数组。
  • 您不能使用.map或.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

以下是他们给我开始的原始def方法:

def new_map(array)
  new_array = []
  array.each do |item|
    # invoke the block, and add its return value to the new array
  end
end

然后这是我当前的代码(更新):

def new_map(a)
  new_array = []
  a.each do |item|
    # invoke the block, and add its return value to the new array.
    yield(item, new_array)
  end
end

a = [2, 3, 4]

new_map(a) do |i, e|
  e << i
end

最后,当我提交刚刚列出的当前代码时,我收到以下错误(已更新):

  

new_map不应该调用地图或地图! (不完全的)

    expected: [2, 3, 4]
     got: [1, 2, 3]

(compared using ==)
exercise_spec.rb:9:in `block (2 levels) in <top (required)>'
  

new_map应映射任何对象(INCOMPLETE)

expected: [Fixnum, String, Symbol]
     got: [1, "two", :three]

(compared using ==)

exercise_spec.rb:14:in `block (2 levels) in <top (required)>'

3 个答案:

答案 0 :(得分:1)

您未能意识到的是,收益率可以返回一个值。块中最后执行的语句是返回值。

因此,您可以从每个yield调用中获取结果并将其添加到结果数组中。

然后,将结果数组作为new_map方法的返回值。

def new_map(a)
  new_array = []
  a.each do |item|
    # invoke the block, and add its return value to the new array.
    new_array << yield(item)
  end
  new_array
end

答案 1 :(得分:1)

试试这个:

def new_map(a)
  new_array = []
  a.each do |item|
    # # invoke the block, and add its return value to the new array.
    puts yield(item) # just experimenting
  end
end

new_map(a) { |i| i + 1 }

这个yield只需要从数组中获取每个元素,然后在块中运行它。这个实验代码只打印结果;这些应该收集在一个数组中。不难:

def new_map(a)
  new_array = []
  a.each do |item|
    new_array = []
    # invoke the block, and add its return value to the new array.
    new_array << yield(item)
  end
end

这不会通过所有测试,但最后一步应该是可行的。

答案 2 :(得分:0)

new_array在定义new_map中创建,这是一个与您在调用new_map时编写的块不同的“词法范围”。基本上,new_map方法中的代码可以看到new_array,但您的块中的代码不能。解决此问题的一种方法可能是查看Enumerable方法injecteach_with_object,它们可以代替您each方法中的new_map。< / p>