我有一个这样的数组数组:
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"]]
我最终需要做的是按日期对数组项进行分组,并对每个子数组的第一项中的数字求和。
因此,输出将类似于:
[[5, "2014-01-27"],
[35, "2014-01-28"],
[20, "2014-01-29"],
[20, "2014-01-30"]]
7条答案
按热度按时间1tuwyuhd1#
ar.group_by(&:last).map{ |x, y| [y.inject(0){ |sum, i| sum + i.first }, x] }
编辑以添加说明:
我们按最后一个值(日期)分组,得到一个哈希值:
然后用
x
作为哈希键,y
作为[[number, date], [number, date]]
对的数组来Map。.inject(0)
意味着sum
从0
开始,然后我们将每个数组的第一项(数字)添加到该总和,直到所有数组都被迭代并且所有数字都被添加。然后我们做
[y, x]
,其中x
是哈希键(日期),y
是所有数字的和。这种方法很有效,因为我们使用injection来避免Map数组两次,并且不必在之后反转值,因为我们在Map时交换了它们的位置。
编辑:有趣的是,@bjhaid和我的答案之间的基准很接近:
1000000
迭代-我的方法最慢oalqel3c2#
r6l8ljro3#
然后你得到一个哈希值,其中的键是日期,值是和,你真的需要结果是一个数组吗?看起来你需要一个散列,但我不知道上下文
也许你甚至不需要在ruby中这样做,如果这些都来自一个db,你可以对查询进行分组和求和
6mzjoqzu4#
说明
第一部分使用Hash.new作为提供给Enumerable#each_with_object的对象来生成
Hash
,它将其键设置为日期(数组的第二个索引),将值设置为数组的第一个索引的和第二部分使用Enumerable#map,它将哈希中的每个
key
,value
对视为一个数组,该数组将被生成到block/proc,在每个生成的对上调用Array#reverse以反转并生成最终数组ryhaxcpt5#
我更喜欢@sawa的解决方案,它使用
group_by
,但这里有另一种方法,有助于说明这里可能的方法的多样性。首先将数组转换为散列,以日期作为键
接下来,将此哈希中的每个值(数组)替换为其元素的总和:
请注意,这个表达式返回一个键数组,但散列
h
现在具有所需的值。因此,我们无法链接到最后的语句:我这样写的原因之一是鼓励你考虑使用哈希
g
作为最终结果,而不是另一个数组。(这也是@sawa的解决方案中前两行之后的h
的值)。考虑这是否在代码中的后续操作中更有意义。大部分内容都很简单,但第一个
each with object
需要一些解释。object
是一个散列,在块中由局部变量h
表示。此哈希由以下人员创建:这使得默认值为空数组。第一次通过块,
d => "2014-01-27"
。由于哈希最初为空,因此它没有密钥"2014-01-27"
。因此,h["2014-01-27"]
被分配了默认值[]
,之后是h["2014-01-27"] << 5
,结果是h => {"2014-01-27" => 5}
。wgxvkvu96#
5m1hhzi47#
我觉得下面这句话没那么深奥