我正在编写一个方法,它接受一个数组并返回另一个数组的平均值,每个数字和数组中的下一个数字。
我尝试使用map
,但一直盯着它看太久,无法看到我出错的地方:
array = [ 1, 3, 5, 1, -10]
array.map! { |a| (a + arr[a+1])/2 }
我期待:
[ 2, 4, 3, -4.5]
答案 0 :(得分:2)
您可以使用Enumerable#each_cons
:
array = [ 1, 3, 5, 1, -10]
array.each_cons(2).map { |a| a.inject(:+) / 2.0 }
#=> [2.0, 4.0, 3.0, -4.5]
将其概括为方法:
def each_cost_avg(array, size = 2)
array.each_cons(size).map { |a| a.inject(:+) / size.to_f }
end
each_cost_avg(array, 2) #=> [2.0, 4.0, 3.0, -4.5]
each_cost_avg(array, 3) #=> [3.0, 3.0, -1.3333333333333333]
each_cost_avg(array, 4) #=> [2.5, -0.25]
答案 1 :(得分:2)
编辑:要注意的关键是您使用数组值索引数组,而不是索引。
你的问题有很多可用的一行答案,所以我会尝试 解决你的代码:
array.map! { |a| (a + arr[a + 1]) / 2 }
使用map
理解的关键是它作用于一个数组并返回一个数组(你使用了map!
,但我们现在可以忽略它。你无法获得地图的平均值,因为它返回一个数组。
例如:
[1, 2, 3, 4].map { |num| num * num } # returns [1, 4, 9, 16]
让我们来看看你的代码,看看它在做什么:
[1, 2, 3].map { |a| (a + arr[a + 1]) / 2 }
第一次调用|a| (a + arr[a + 1]) / 2
,a
将为1.因此返回数组的第一个元素为1 + arr[1 + 1] / 2 = 1 + 3 / 2 ~= 2
等等。显然,这不是你想要的。
现在对于一行解决方案(我从here获取此内容):
arr.inject { |sum, el| sum + el }.to_f / arr.size
inject
与reduce
相同,在某些语言中为foldr
。这比map
复杂一点。基本上方法|sum, el| sum + el
应用于前两个元素,并将其结果应用于第三个元素,依此类推,直到数组结束。
因此,如果我们的数组是[1, 2, 3, 4]
,则算术调用堆栈可能如下所示:
((1 + 2) + 3) + 4
使用这两种方法,您应该能够完成所需的操作,即一组平均值。或者至少这应该有助于您了解其他解决方案。