Ruby 块(产量)
Ruby Blocks (Yield)
我才刚刚开始学习 Ruby,我在 Bloc 的课程已经很顺利了,但现在我被困在一个关于 yield 和 blocks 的练习中(我发现这是学习时迄今为止最难掌握的概念 ruby)。
以下是纯格式文本所需的规范:
- 定义一个new_map方法
- 它应该接受一个数组作为参数,return一个根据作为块传入的指令修改的新数组。
- 您不能使用.map 或.map!方法
- 但是,请随意在方法中使用每个
- 您需要将每个块调用的 return 值存储在一个新数组中
- 它应该映射任何对象
以下是需要满足的 RSpecs:
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 should not call map or map! (INCOMPLETE)
expected: [2, 3, 4]
got: [1, 2, 3]
(compared using ==)
exercise_spec.rb:9:in `block (2 levels) in <top (required)>'
new_map should map any object (INCOMPLETE)
expected: [Fixnum, String, Symbol]
got: [1, "two", :three]
(compared using ==)
exercise_spec.rb:14:in `block (2 levels) in <top (required)>'
new_array
是在定义 new_map
中创建的,与调用 new_map
时编写的块不同 "lexical scope"。基本上,new_map
方法中的代码可以看到 new_array
,但您的块中的代码不能。解决此问题的一种方法可能是查看 Enumerable
方法 inject
或 each_with_object
可以代替 new_map
方法中的 each
。
您没有意识到 yield 可以 return 一个值。块中最后执行的语句是 returned 值。
因此您可以从每个 yield 调用中获取结果并将其添加到结果数组中。
然后,将结果数组作为您的 new_map
方法的 return 值。
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
试试这个:
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
这不会通过所有测试,但最后一步应该是可行的。
我才刚刚开始学习 Ruby,我在 Bloc 的课程已经很顺利了,但现在我被困在一个关于 yield 和 blocks 的练习中(我发现这是学习时迄今为止最难掌握的概念 ruby)。
以下是纯格式文本所需的规范:
- 定义一个new_map方法
- 它应该接受一个数组作为参数,return一个根据作为块传入的指令修改的新数组。
- 您不能使用.map 或.map!方法
- 但是,请随意在方法中使用每个
- 您需要将每个块调用的 return 值存储在一个新数组中
- 它应该映射任何对象
以下是需要满足的 RSpecs:
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 should not call map or map! (INCOMPLETE)
expected: [2, 3, 4]
got: [1, 2, 3]
(compared using ==)
exercise_spec.rb:9:in `block (2 levels) in <top (required)>'
new_map should map any object (INCOMPLETE)
expected: [Fixnum, String, Symbol]
got: [1, "two", :three]
(compared using ==)
exercise_spec.rb:14:in `block (2 levels) in <top (required)>'
new_array
是在定义 new_map
中创建的,与调用 new_map
时编写的块不同 "lexical scope"。基本上,new_map
方法中的代码可以看到 new_array
,但您的块中的代码不能。解决此问题的一种方法可能是查看 Enumerable
方法 inject
或 each_with_object
可以代替 new_map
方法中的 each
。
您没有意识到 yield 可以 return 一个值。块中最后执行的语句是 returned 值。
因此您可以从每个 yield 调用中获取结果并将其添加到结果数组中。
然后,将结果数组作为您的 new_map
方法的 return 值。
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
试试这个:
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
这不会通过所有测试,但最后一步应该是可行的。