gpt4 book ai didi

ruby - Array.first 与 Ruby 中的 Array.shift

转载 作者:数据小太阳 更新时间:2023-10-29 07:32:09 24 4
gpt4 key购买 nike

我实际上是在练习重写 Enumerable 模块中注入(inject)方法的基本形式,而我的解决方案没有做任何事情,因为我使用的是#first:

def injecting(*acc, &block)
acc = acc.empty? ? self.first : acc.first
self.each do |x|
acc = block.call(acc, x)
end
acc
end

然后我遇到了另一个使用#shift 而不是#first 的解决方案并且工作得很好:

def injecting(*acc, &block)
acc = acc.empty? ? self.shift : acc.first
self.each do |x|
acc = block.call(acc, x)
end
acc
end

我知道 #first 返回数组的第一个元素,但在 #shift 返回并改变它时不会改变它,但我很难理解如果你通过删除第一个元素来改变数组:

[1,2,3].injecting { |a,x| a + x } # --> 6

任何智慧的话将不胜感激..

谢谢!

最佳答案

只需添加一行 p acc 即可对其进行调试。

(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.shift : acc.first
| p acc
| self.each do |x|
| acc = block.call(acc, x)
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
1
=> 6
>>

当您在数组 [1,2,3] 上调用方法 injecting 时,由于 acc 为空,sef .shift 被调用。现在 acc1。现在 self 只有 [2,3]。所以调用 self.each.. 首先传递 2,然后调用 block 并将 a = x 的结果分配给 acc,whis 现在持有 3。所以现在在下一次迭代中,从 self 传递下一个值(3),并再次调用 block ,并再次执行 a + x,所以现在 acc 的值是 6。所以你得到了结果 6

多一级调试:

(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.shift : acc.first
| p "acc now holds #{acc}"
| p "elements in self is #{self}"
| self.each do |x|
| acc = block.call(acc, x)
| p "current value of acc is #{acc}"
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
"acc now holds 1"
"elements in self is [2, 3]"
"current value of acc is 3"
"current value of acc is 6"
=> 6
>>

As per OP's comment

Am I safe assuming that by calling first, is still returning the 1st item but starts the iteration from that item, hence why I would get 7?

我再次建议您添加一些调试消息,以查看幕后情况。看下面:

(arup~>~)$ pry --simple-prompt
>> module Enumerable
| def injecting(*acc, &block)
| acc = acc.empty? ? self.first : acc.first
| p "acc now holds #{acc}"
| p "elements in self is #{self}"
| self.each do |x|
| acc = block.call(acc, x)
| p "current value of acc is #{acc}"
| end
| acc
| end
| end
=> nil
>> [1,2,3].injecting { |a,x| a + x }
"acc now holds 1"
"elements in self is [1, 2, 3]"
"current value of acc is 2"
"current value of acc is 4"
"current value of acc is 7"
=> 7
>>

self.first 只返回第一个元素,即 1,并分配给 acc。但是 self 没有被修改。但是在 self.shift 的情况下,1 被分配给 acc 并且同时从 self 中删除>,然后 self[2,3]

现在这部分,self.each..代码传递了self的3个值,分别是1,23。现在求和是6,加上1,这是第一个acc值,当self.first被叫到。这就是acc的最终结果是7

关于ruby - Array.first 与 Ruby 中的 Array.shift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21501506/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com