我有点困惑为什么这个答案是"错误"基于Ruby自己对" Inject"的解释。方法(对于这种情况下的数组,我正在做" Odin项目"用于学习任务的项目)
def my_inject(start = nil)
memo = self[0] if start.nil?
for i in 0...self.length do
puts "#{memo}:#{self[i]} Results=#{yield(memo,self[i])}"
memo = yield(memo,self[i])
end
return memo
end
[5,6,7,8,9,10].my_inject { |sum, n| sum + n }
以上具体回复:
5:5 Results=10
10:6 Results=16
16:7 Results=23
23:8 Results=31
31:9 Results=40
40:10 Results=50
=> 50
哪个有道理?如果未定义起始值,则使用第一个值。但是根据Ruby的API文档:"Inject"它应该是45 ....
这对我没有意义。我们从第一个值的备忘录开始,并将其添加到"元素"值。这是10(在这种情况下)......等等。或者他们在你没有指定价值时说?你应该跳过第一个数组值吗?
我的意思是如果我加上5 + 6 + 7 + 8 + 9 + 10是的,这是正确的45,但如果我正在做阻止我要做的事情,我觉得" 50"更有意义吗?虽然显然我错了,我只是不确定在哪里。
我的意思是如果我们没有给出一个起始值,我可以确定我可以在1处开始索引......但这看起来很奇怪。
由于
答案 0 :(得分:3)
正如人们在评论中指出的那样,如果没有提供参数,你的解决方案会双击第一个元素。
这是一个非常简单的实现,删除了您的解决方案中包含的一些不必要的元素,并且不仅适用于数组:
module Enumerable
def my_inject(memo = nil)
each { |x| memo = memo.nil? ? x : yield(memo, x) }
memo
end
end
p (1..5).my_inject(&:*) # 5 factorial => 120
p (1..5).my_inject(2, &:*) # 5 factorial doubled => 240
p %w(3 4 5).my_inject(&:+) # string concatenation => "345"
p %w(3 4 5).my_inject("hello", &:+) # concatenation w/ prefix => "hello345"
p %w(3 4 5).my_inject("howdy") { |memo, x| memo + x } # prefix and block => "howdy345"
<强>附录强>
如果您想进一步处理Symbol
或String
Enumerable#inject
参数,您需要进行一些预处理以确定您要处理的内容:
module Enumerable
def my_inject(memo = nil, sym = nil, &block)
memo = memo.to_sym if memo.is_a?(String) && !sym && !block
block, memo = memo.to_proc, nil if memo.is_a?(Symbol) && !sym
sym = sym.to_sym if sym.is_a?(String)
block = sym.to_proc if sym.is_a?(Symbol)
# Ready to rock & roll
each { |x| memo = memo.nil? ? x : block.yield(memo, x) }
memo
end
end
# A variety of test cases
p (1..4).my_inject(:*) # 4 factorial via Symbol => 24
p (1..5).my_inject('*') # 5 factorial via String => 120
p (1..6).my_inject { |memo, x| memo * x } # 6 factorial via block => 720
p (1..5).my_inject(2, &:*) # 5 factorial doubled via Proc => 240
p (1..5).my_inject(3, :*) # 5 factorial tripled via Symbol => 360
p (1..5).my_inject(4, '*') # 5 factorial quadrupled via String => 480
p %w(3 4 5).my_inject(&:+) # string concatenation via Proc => "345"
p %w(3 4 5).my_inject("hello", &:+) # prefix and Proc => "hello345"
p %w(3 4 5).my_inject("howdy") { |memo, x| memo + x } # prefix and block => "howdy345"
p %w(3 4 5).my_inject("yowza", :+) # prefix and Symbol => "yowza345"
p %w(3 4 5).my_inject("yoiks", '+') # prefix and String => "yoiks345"