Ruby 将数组转换为散列同时删除重复键并添加值
我有一个数组,看起来是这样的:Ruby 将数组转换为散列同时删除重复键并添加值,ruby,arrays,hash,enumerable,Ruby,Arrays,Hash,Enumerable,我有一个数组,看起来是这样的: f = [["Wed, 12-31", 120.0],["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]] 我可以将其转换为哈希并删除重复的密钥: h = Hash[ *f.collect { |v| [v] }.flatten ] # => {"Wed, 12-31"=>120.0, "Thu, 01-01"=>120.0} 这差不多了,但我想对具有相同日期字符串的元素的值求和,上面数组的期望结果如下:
f = [["Wed, 12-31", 120.0],["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]]
我可以将其转换为哈希并删除重复的密钥:
h = Hash[ *f.collect { |v| [v] }.flatten ]
# => {"Wed, 12-31"=>120.0, "Thu, 01-01"=>120.0}
这差不多了,但我想对具有相同日期字符串的元素的值求和,上面数组的期望结果如下:
{"Wed, 12-31"=>120.0, "Thu, 01-01"=>240.0}
我如何才能做到这一点?这一点很有效:
result = Hash.new(0)
f = [["Wed, 12-31", 120.0],["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]]
f.each { |subarray| result[subarray[0]] += subarray[1] }
puts result
如果您想成为花花公子,您可以使用.inject()
此功能:
result = Hash.new(0)
f = [["Wed, 12-31", 120.0],["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]]
f.each { |subarray| result[subarray[0]] += subarray[1] }
puts result
如果您想成为一名花花公子,您可以使用.inject()
我会使用:
我会使用:
解决此类问题的另一种标准方法是: 我们有:
a = ary.group_by(&:first)
#=> {"Wed, 12-31"=>[["Wed, 12-31", 120.0]],
# "Thu, 01-01"=>[["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]]}
b = a.map { |d,a| [d, a.reduce(0) { |t,(_,n)| t+n }] }
#=> [["Wed, 12-31", 120.0], ["Thu, 01-01", 240.0]]
Hash[b]
#=> {"Wed, 12-31"=>120.0, "Thu, 01-01"=>240.0}
或者使用Ruby 2.0+:
b.to_h
#=> {"Wed, 12-31"=>120.0, "Thu, 01-01"=>240.0}
这方面的一个变体是:
ary.group_by(&:first).map { |d,a| [d, a.transpose.last.reduce(:+) ] }.to_h
解决此类问题的另一种标准方法是: 我们有:
a = ary.group_by(&:first)
#=> {"Wed, 12-31"=>[["Wed, 12-31", 120.0]],
# "Thu, 01-01"=>[["Thu, 01-01", 120.0], ["Thu, 01-01", 120.0]]}
b = a.map { |d,a| [d, a.reduce(0) { |t,(_,n)| t+n }] }
#=> [["Wed, 12-31", 120.0], ["Thu, 01-01", 240.0]]
Hash[b]
#=> {"Wed, 12-31"=>120.0, "Thu, 01-01"=>240.0}
或者使用Ruby 2.0+:
b.to_h
#=> {"Wed, 12-31"=>120.0, "Thu, 01-01"=>240.0}
这方面的一个变体是:
ary.group_by(&:first).map { |d,a| [d, a.transpose.last.reduce(:+) ] }.to_h
注意,您可以将数组转换为散列,丢弃重复的键,而无需使用
.collect.flatte
无意义。只需使用散列[array]
f.collect{| v |[v]}
只是将数组映射到自身。它没有任何作用.flant
在一个已经平坦的数组上同样是无用的。@KennyMeyer,谷歌?感谢您提供有关.collect
和.flatte
的提示。注意,您可以将数组转换为散列,丢弃重复键,而无需使用.collect.flatte
命令。只需使用散列[array]
f.collect{| v |[v]}
只是将数组映射到自身。它没有任何作用.flant
在一个已经平坦的数组上同样是无用的。@KennyMeyer,谷歌?感谢您在上提供的提示。收集和。展平如果您想更喜欢和更懒,请使用每个带有对象的对象,而不是注入。如果你想变得更花哨、更懒,可以使用每个带有对象的对象,而不是注入。它工作起来更干净。感谢Ruby的2.0+to_h
方法!这是rad。感谢Ruby的2.0+到h
方法!这是rad。我想补充一点,在我接受@kennymeyer的答案时,我后来切换到了这个解决方案。只是重申一下你偶尔会在堆栈溢出上看到的东西:不要选择出现的第一个答案来回答你的问题。做某事的方法有很多种,人们不会在电脑前等待问题的解决。答案有时需要一段时间才能形成;我经常等待回答,希望有人会回应我认为是做某事的正确方式,然后如果没有人做过,我会补充我的答案,或者回答我认为答案应该是彻底的。所以,提问,然后等待一天,看看会出现什么。我想补充一点,当我接受@kennymeyer的答案时,我后来切换到了这个解决方案。只是重申一下你偶尔会在堆栈溢出上看到的东西:不要选择出现的第一个答案来回答你的问题。做某事的方法有很多种,人们不会在电脑前等待问题的解决。答案有时需要一段时间才能形成;我经常等待回答,希望有人会回应我认为是做某事的正确方式,然后如果没有人做过,我会补充我的答案,或者回答我认为答案应该是彻底的。所以,问问,然后等一天,看看会出现什么。