在ruby中将一个哈希转换为另一个哈希
将以下哈希转换为另一个哈希在ruby中将一个哈希转换为另一个哈希,ruby,ruby-on-rails-3,Ruby,Ruby On Rails 3,将以下哈希转换为另一个哈希 {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789", "user1"]=>5} 将上面的散列转换为 {["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1} 正如您看到的第一个键和第二个键一样,散列中的值对具有相同的日期, 不同的帐户,相同的用户
{["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789", "user1"]=>5}
将上面的散列转换为
{["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1}
正如您看到的第一个键和第二个键一样,散列中的值对具有相同的日期,
不同的帐户,相同的用户,在这种情况下,我需要计算总数
作为两个{[“2013-08-15”,“user1”]=>2}
在最后一个键、值对中,计数应为1,因为用户发布到
只有一个帐户(“789”),即使有5篇帖子
{[“2013-08-09”,“user1”]=>1}
不是很优雅,但很有效。另外,使用数组作为散列键有点奇怪
h = {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789", "user1"]=>5}
h.inject(Hash.new(0)){|a,((date,post,user),v)| a[[date,user]] +=1; a } # => {["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1}
或者
请注意,您需要使用.to_i方法进行首次初始化,否则我们将添加nil,但这将使其为0。使用“您可以编写此干净且模块化的一行程序:
require 'facets'
hash1 = {["2013-08-15", "123", "user1"] => 1, ...}
hash2 = hash1.keys.map { |date, code, user| [date, user] }.frequency
#=> {["2013-08-15", "user1"] => 2, ["2013-08-09", "user1"] => 1}
请注意,解压缩数组的值可以更容易地查看发生了什么。另外,请注意,您不需要依赖于方面,只需将Enumerable#frequency
添加到扩展库中,这是一种非常常见的抽象。这可以通过和完成:
@当然可以。IIRC任何对象都可以用作哈希键,如果它响应
hash
和eql?
@mbrach,当然可以<代码>{[1]=>'foo'}[[1]]返回foo
。我得到了这个错误hash1.keys.map{| date,code,user |[date,user]}。频率命名错误:未定义#的方法`频率';当然,您需要安装facets:gem install facets
+1。注意:虽然我非常喜欢FP,其中使用\uuuu
表示“whatever”是一个常见的习惯用法,但我更喜欢为未使用的变量命名,这一点更清楚。至少在Ruby中它看起来很奇怪。
h = {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789","user1"]=>5}
h.each_with_object(Hash.new(0)){|((d,_,u),_),hsh| hsh[[d,u]] +=1 }
# => {["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1}
hash1 = {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789", "user1"]=>5}
hash2 = Hash.new
hash1.each do |x,y|
hash2[ [x[0],x[2]] ] = hash2[ [x[0],x[2]] ].to_i + 1
end
puts hash2
require 'facets'
hash1 = {["2013-08-15", "123", "user1"] => 1, ...}
hash2 = hash1.keys.map { |date, code, user| [date, user] }.frequency
#=> {["2013-08-15", "user1"] => 2, ["2013-08-09", "user1"] => 1}
h = {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789", "user1"]=>5}
Hash[h.group_by { |(u, _, d), _| [u, d] }.map { |u, d| [u, d.size] }]
#=> {["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1}