编写Ruby注入方法?
基于Ruby自己对“Inject”方法的解释,我有点困惑为什么这个答案是“错误的”(对于本例中的数组,我在做“Odin项目”项目以完成学习任务) 上面具体返回了这一点:编写Ruby注入方法?,ruby,Ruby,基于Ruby自己对“Inject”方法的解释,我有点困惑为什么这个答案是“错误的”(对于本例中的数组,我在做“Odin项目”项目以完成学习任务) 上面具体返回了这一点: 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文档:应该是45 这对我来说毫无意义。我们从
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文档:应该是45
这对我来说毫无意义。我们从第一个值的备注开始,并将其添加到“elements”值中。这是10(在本例中)…以此类推。或者他们是说当你没有指定一个值的时候?是否应跳过第一个数组值
我的意思是,如果我把5+6+7+8+9+10加起来,是的,这是正确的45,但是如果我做的是街区想要我做的,我觉得“50”更有意义?虽然很明显我错了,但我不知道在哪里
我的意思是,如果我们没有给出一个起始值,我肯定可以将指数从1开始…但这似乎很奇怪
谢谢正如人们在评论中指出的那样,如果没有提供参数,您的解决方案将双击第一个元素 这是一个非常简单的实现,删除了您的解决方案中包含的一些不必要的元素,并且不仅仅适用于阵列:
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"
正如人们在评论中指出的,如果没有提供参数,您的解决方案将双击第一个元素 这是一个非常简单的实现,删除了您的解决方案中包含的一些不必要的元素,并且不仅仅适用于阵列:
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"
我想你已经回答了你自己的问题。。。5+6+7+8+9+10=45——因此我认为该方法返回45而不是50显然是最有意义的。为什么您认为50更有意义?是的,实现是“如果您不提供初始值,那么迭代器将跳过它”。这种实现提供了“毫不奇怪”的行为,不像您的方法对第一个数组元素进行双重计数。您的整个推理听起来好像是基于“您认为应该如何定义该方法”,而不是更符合逻辑的问题:“该方法应返回什么?”请注意,Ruby代码很少使用
for
,因为方法和相关的帮助程序要灵活得多。此外,Ruby方法末尾的return
是多余的,这些值是隐式返回的,因此在这种情况下,只需memo
就足够了。我想这让我感到困惑,因为是的,我意识到它错了,我意识到它双击了第一个元素……但我只是认为它正在尝试运行块……所以“memo”在这种情况下,它的值为5。所以5+5。,这在积木方面是有意义的,但在整体考虑问题时是没有意义的。我想你已经回答了你自己的问题。。。5+6+7+8+9+10=45——因此我认为该方法返回45而不是50显然是最有意义的。为什么您认为50更有意义?是的,实现是“如果您不提供初始值,那么迭代器将跳过它”。这种实现提供了“毫不奇怪”的行为,不像您的方法对第一个数组元素进行双重计数。您的整个推理听起来好像是基于“您认为应该如何定义该方法”,而不是更符合逻辑的问题:“该方法应返回什么?”请注意,Ruby代码很少使用for
,因为方法和相关的帮助程序要灵活得多。此外,Ruby方法末尾的return
是多余的,这些值是隐式返回的,因此在这种情况下,只需memo
就足够了。我想这让我感到困惑,因为是的,我意识到它错了,我意识到它双击了第一个元素……但我只是认为它正在尝试运行块……所以“memo”在这种情况下,它的值为5。所以5+5..这在块方面是有意义的,但在考虑整个问题时是没有意义的。我认为当你看块sum+n
时,双击参数是有意义的,这就是所传递的。在这种情况下,“和”是5(使用第一个值),n是第一个值(所以5+5)…这显然是错误的。我认为我的解释过于字面化,因为当我在Ruby文档中看到“它使用第一个数组元素作为和”时,我认为我应该将第一个数组元素传入块中并正常运行(我理解这是错误的),我认为Tom Lord解释得很好,inject
的sum应该是对值求和,因此45是您示例的正确答案。我认为当您查看正在传递的块sum+n
时,双击参数是有意义的。在这种情况下,“和”是5(使用第一个值),n是第一个值(所以5+5)…这显然是错误的。我认为我的解释过于字面化,因为当我在Ruby文档中看到“它使用第一个数组元素作为和”时,我认为我应该将第一个数组元素传入块中并正常运行(我理解这是错误的),我认为Tom Lord解释得很好,inject
使用一个sum应该对值求和,因此45是您的示例的正确答案。