0

将以下哈希转换为另一个哈希。

{["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,因为即使有 5 个帖子,用户也只发布到一个帐户(“789”){["2013-08-09", "user1"]=>1}

4

5 回答 5

3

使用FacetsEnumerable#frequency您可以编写这个干净且模块化的单行代码:

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}

请注意,解压缩数组的值可以更轻松地查看发生了什么。另外,请注意您不需要依赖 Facets,只需添加Enumerable#frequency到您的扩展库中,这是一个非常常见的抽象。

于 2013-08-19T18:03:07.863 回答
2

不是超级优雅但有效。此外,使用数组作为哈希键有点奇怪。

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}
于 2013-08-19T17:47:27.527 回答
2
h = {["2013-08-15", "123", "user1"]=>1, ["2013-08-15", "456", "user1"]=>1, ["2013-08-09", "789","user1"]=>5} 
Hash[h.group_by{|k,v| k[0]}.map{|_,v| [v.flatten.values_at(0,2),v.size]}]
# => {["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} 
h.each_with_object(Hash.new(0)){|((d,_,u),_),hsh| hsh[[d,u]] +=1 }
# => {["2013-08-15", "user1"]=>2, ["2013-08-09", "user1"]=>1}
于 2013-08-19T17:47:48.257 回答
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

请注意,您需要使用 .to_i 方法进行首次初始化,否则我们将使用nil添加,但这使其为 0。

于 2013-08-19T17:48:11.773 回答
1

这可以通过group_byand来完成map

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}
于 2013-08-19T20:25:58.400 回答