我是一个红宝石新手,学习编码。我想了解Enumerable模块中可用的某些方法是如何工作的。所以我重新实现了它们。一个挑战是使用递归来实现它们。但是,在尝试使用递归实现Enumerable#Map方法时遇到了问题。
这是我的代码:
class Array
def mymap_recursive(&block)
copy_of_array = dup
new_array = []
return new_array if copy_of_array.empty?
value = copy_of_array.shift
new_array << yield(value)
copy_of_array.mymap_recursive(&block)
end
end
我试图找出它为什么不起作用所以我把
puts "#{new_array}"
在方法结束时。然后在Sublime Text中,我做了
arr = [2,2,5,5,10]
arr.mymap_recursive {|n| n * n}
按下cmd + b后,我得到的输出是:
[100]
[25]
[25]
[4]
[4]
我无法弄清楚为什么它没有返回一个包含所有值的数组。
感谢您的帮助!
答案 0 :(得分:2)
每次拨打mymap_recursive(&block)
new_array
时,您的代码中发生的事情都会丢失。要解决这个问题,您必须有办法维护递归构建的新数组。对代码进行简单更改的方法是在方法定义中包含new_array = []
,然后每次都传递新数组。这将是我的更改的代码:
class Array
def mymap_recursive(new_array = [], &block)
copy_of_array = self.dup
return new_array if copy_of_array.empty?
value = copy_of_array.shift
new_array << yield(value)
copy_of_array.mymap_recursive(new_array, &block)
end
end
然后当你打电话
arr = [2,2,5,5,10]
p arr.mymap_recursive {|n| n * n}
#returns
#[4, 4, 25, 25, 100]
如果您对此语法有任何疑问或有任何问题请与我联系,我会尽力解释一下!
答案 1 :(得分:1)
另一种解决方案,它不会改变方法签名并且不会改变任何数据:
class Array
def mymap_recursive(&block)
if empty?
[]
else
[block.call(first)] + drop(1).mymap_recursive(&block)
end
end
end