我希望获得inject
的每个值。
例如[1,2,3].inject(3){|sum, num| sum + num}
返回9
,我想得到循环的所有值。
我尝试了[1,2,3].inject(3).map{|sum, num| sum + num}
,但它没有用。
我写的代码是这样的,但我觉得它是多余的。
a = [1,2,3]
result = []
a.inject(3) do |sum, num|
v = sum + num
result << v
v
end
p result
# => [4, 6, 9]
有没有办法同时使用inject
和map
?
答案 0 :(得分:5)
使用专用的Eumerator
非常适合这里,但我会为此展示更通用的方法:
[1,2,3].inject(map: [], sum: 3) do |acc, num|
acc[:map] << (acc[:sum] += num)
acc
end
#⇒ => {:map => [4, 6, 9], :sum => 9}
那样(使用哈希作为累加器)可以收集她想要的任何东西。 Sidenote :更好地使用Enumerable#each_with_object
而不是inject
,因为前者在每次后续迭代中都不会生成对象的新实例:
[1,2,3].each_with_object(map: [], sum: 3) do |num, acc|
acc[:map] << (acc[:sum] += num)
end
答案 1 :(得分:1)
我能想到的最好的
def partial_sums(arr, start = 0)
sum = 0
arr.each_with_object([]) do |elem, result|
sum = elem + (result.empty? ? start : sum)
result << sum
end
end
partial_sums([1,2,3], 3)
答案 2 :(得分:1)
您可以使用枚举器:
enum = Enumerator.new do |y|
[1, 2, 3].inject (3) do |sum, n|
y << sum + n
sum + n
end
end
enum.take([1,2,3].size) #=> [4, 6, 9]
显然你可以很好地将它包装在一个方法中,但是我会留给你做的。也不要认为你的尝试有很多错误,效果很好。
答案 3 :(得分:1)
def doit(arr, initial_value)
arr.each_with_object([initial_value]) { |e,a| a << e+a[-1] }.drop 1
end
arr = [1,2,3]
initial_value = 4
doit(arr, initial_value)
#=> [5, 7, 10]
这有助于推广。
def gen_doit(arr, initial_value, op)
arr.each_with_object([initial_value]) { |e,a| a << a[-1].send(op,e) }.drop 1
end
gen_doit(arr, initial_value, :+) #=> [5,7,10]
gen_doit(arr, initial_value, '-') #=> [3, 1, -2]
gen_doit(arr, initial_value, :*) #=> [4, 8, 24]
gen_doit(arr, initial_value, '/') #=> [4, 2, 0]
gen_doit(arr, initial_value, :**) #=> [4, 16, 4096]
gen_doit(arr, initial_value, '%') #=> [0, 0, 0]