如何在Ruby中对数组进行分组和求和? [英] How to group and sum arrays in Ruby?
问题描述
我有一个这样的数组数组:
I have an array of arrays like this:
ar = [[5, "2014-01-27"],
[20, "2014-01-28"],
[5, "2014-01-28"],
[10, "2014-01-28"],
[15, "2014-01-29"],
[5, "2014-01-29"],
[5, "2014-01-30"],
[10, "2014-01-30"],
[5, "2014-01-30"]]
我最终要做的是按日期对数组项进行分组,并对每个子数组的第一项中的数字求和。
What I ultimately need to do is group the array items by date and sum up the numbers in the first item of each sub-array.
因此输出将类似于:
[[5, "2014-01-27"],
[35, "2014-01-28"],
[20, "2014-01-29"],
[20, "2014-01-30"]]
推荐答案
ar.group_by(&:last).map { | x,y | [y.inject(0){| sum,i | sum + i.first},x]}
编辑添加解释:
我们将最后一个值分组(日期)产生的哈希值:
Edit to add explanation:
We group by the last value (the date) yielding a hash:
{"2014-01-27"=>[[5, "2014-01-27"]], "2014-01-28"=>[[20, "2014-01-28"], [5, "2014-01-28"], [10, "2014-01-28"]], "2014-01-29"=>[[15, "2014-01-29"], [5, "2014-01-29"]], "2014-01-30"=>[[5, "2014-01-30"], [10, "2014-01-30"], [5, "2014-01-30"]]}
然后使用 x
作为散列键和 y
作为 [[数字,日期],[数字,日期]]
对的数组。
Then map that with x
as they hash key, and y
as the array of [[number, date], [number, date]]
pairs.
.inject(0)
表示 sum
开始设为 0
,然后将每个数组的第一项(数字)添加到该总和中,直到迭代所有数组并添加所有数字。
.inject(0)
means sum
starts out as 0
, then we add the first item of each array (the number) to that sum until all arrays are iterated and all the numbers are added.
然后我们做 [y,x]
其中 x
是哈希键(日期), y
是所有数字的总和。
Then we do [y, x]
where x
is the hash key (the date), and y
is the sum of all the numbers.
此方法非常有效,因为我们使用inject避免两次映射该数组,并且以后不必反转值,因为我们在映射时交换了它们的位置。
This method is efficient as we use inject to avoid mapping the array twice and don't have to reverse the values afterwards since we swapped their positions while mapping it.
编辑:有趣的是@bjhaid与我的答案之间的基准线接近:
Interestingly the benchmarks between @bjhaid and my answer are close:
user system total real
5.117000 0.000000 5.117000 ( 5.110292)
5.632000 0.000000 5.632000 ( 5.644323)
1000000
次迭代-我的方法最慢
1000000
iterations - my method was the slowest
这篇关于如何在Ruby中对数组进行分组和求和?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!