使用递归重写 Ruby #inject (#reduce)?
Rewriting Ruby #inject (#reduce) using recursion?
编码新手,已经了解了 Ruby 中一些更常用的方法,猴子修补它们以更好地理解每种方法的工作原理(顺便说一句,这帮助很大)。
现在我又在做同样的事情,但是对于我之前迭代过的那些,我正在使用递归。我的问题是:
我正在为 Array
class 创建自己的 #inject
方法,我想递归地编写它。该方法将允许传递可选的累加器以及过程。使用以下格式如何完成?
class Array
def my_inject(accum = nil, &prc)
#code
end
end
此外,我是否需要担心改变原始数组,我应该使用 #dup
吗?提前感谢您的帮助!
我想我明白了!
class Array
def my_inject(acc=nil, &prc)
return acc if empty?
acc = self.shift if acc.nil?
acc = prc.call(acc, self.first)
self.shift
my_inject(acc, &prc)
end
end
我唯一的问题是这会不会有问题/它会改变原始数组吗?
编辑:添加了不改变原始版本的版本。
class Array
def my_inject(acc=nil, &prc)
new_arr = self.dup
return acc if empty?
acc = new_arr.shift if acc.nil?
acc = prc.call(acc, self.first)
new_arr.shift
my_inject(acc, &prc)
end
end
另一种实现方式
class Array
def aggregate(accumulator = nil, &sumator)
return accumulator if empty?
drop(1).aggregate(accumulator ? sumator.(accumulator, first) : first, &sumator)
end
end
至于您是否应该担心原始版本的变异 - 简而言之 - 是的。通常 Ruby 中的方法如果可能不会改变对象并制作副本。经常有 bang (!
) 替代品。所述 "dangerous" 方法在原地改变原件而不是返回副本。但是,在这种情况下,这是没有意义的。原为数组,结果为求和。
至于对原件进行变异并单独返回结果,除非你有真正的性能(或其他)考虑,否则你不应该这样做。这是不直观的,可能会导致混乱的情况。
编码新手,已经了解了 Ruby 中一些更常用的方法,猴子修补它们以更好地理解每种方法的工作原理(顺便说一句,这帮助很大)。
现在我又在做同样的事情,但是对于我之前迭代过的那些,我正在使用递归。我的问题是:
我正在为 Array
class 创建自己的 #inject
方法,我想递归地编写它。该方法将允许传递可选的累加器以及过程。使用以下格式如何完成?
class Array
def my_inject(accum = nil, &prc)
#code
end
end
此外,我是否需要担心改变原始数组,我应该使用 #dup
吗?提前感谢您的帮助!
我想我明白了!
class Array
def my_inject(acc=nil, &prc)
return acc if empty?
acc = self.shift if acc.nil?
acc = prc.call(acc, self.first)
self.shift
my_inject(acc, &prc)
end
end
我唯一的问题是这会不会有问题/它会改变原始数组吗?
编辑:添加了不改变原始版本的版本。
class Array
def my_inject(acc=nil, &prc)
new_arr = self.dup
return acc if empty?
acc = new_arr.shift if acc.nil?
acc = prc.call(acc, self.first)
new_arr.shift
my_inject(acc, &prc)
end
end
另一种实现方式
class Array
def aggregate(accumulator = nil, &sumator)
return accumulator if empty?
drop(1).aggregate(accumulator ? sumator.(accumulator, first) : first, &sumator)
end
end
至于您是否应该担心原始版本的变异 - 简而言之 - 是的。通常 Ruby 中的方法如果可能不会改变对象并制作副本。经常有 bang (!
) 替代品。所述 "dangerous" 方法在原地改变原件而不是返回副本。但是,在这种情况下,这是没有意义的。原为数组,结果为求和。
至于对原件进行变异并单独返回结果,除非你有真正的性能(或其他)考虑,否则你不应该这样做。这是不直观的,可能会导致混乱的情况。