Ruby将哈希转换为csv中的直方图

时间:2016-05-28 04:10:32

标签: ruby-on-rails ruby csv hash

我有一个看起来像这样的哈希:

@histogram = {
  "Date 1" => [
     {"Item 1" => 1},
     {"Item 4" => 3}
  ],
  "Date 2" => [
     {"Item 2" => 7},
     {"Item 1" => 2},
     {"Item 5" => 1}
  ],
  "Date 3" => [
     {"Item 4" => 3},
     {"Item 2" => 2},
     {"Item 8" => 1},
     {"Item 1" => 5}
  ]
}

我想将其转换为日常直方图CSV文件,如下所示:

|        | Date 1 | Date 2 | Date 3 |
| Item 1 |   1    |   2    |   5    |
| Item 2 |        |   7    |   2    |
| Item 4 |   3    |        |   3    |
| Item 5 |        |   1    |        |
| Item 8 |        |        |   8    |

绊倒我的是@histogram哈希可能完全无序。日期(keys)可能是有序的,但项目将完全失灵。此外,正如您所看到的,这些项目在不同日期不必相同。如果某个项目在特定日期不存在,则直方图中的数量可以假定为0.

1 个答案:

答案 0 :(得分:0)

我没有看到有Date1值的哈希数组的重点,它很可能是具有多个键的单个哈希。 @histogram的结构最好如下所示:

{"Date 1"=>{"Item 1"=>1, "Item 4"=>3},
 "Date 2"=>{"Item 2"=>7, "Item 1"=>2, "Item 5"=>1},
 "Date 3"=>{"Item 4"=>3, "Item 2"=>2, "Item 8"=>1, "Item 1"=>5}}

因此,我将提供将@histogram转换为上述结构的解决方案,并在此基础上构建。

processed_hash = @histogram.map {|k,v| [k, v.reduce(&:merge)]}.to_h

column_headers =  processed_hash.keys
row_headers = processed_hash.flat_map{ |k, v| v.keys}.uniq.sort

print "|" + "".center(10) + "|"
column_headers.each {|ch| print ch.center(10) + "|"}
puts
row_headers.each do |rh|
  print "|" +  rh.center(10) + "|"
  column_headers.each {|ch| print processed_hash.dig(ch, rh).to_s.center(10) + "|"}
  puts
end

输出:

|          |  Date 1  |  Date 2  |  Date 3  |
|  Item 1  |    1     |    2     |    5     |
|  Item 2  |          |    7     |    2     |
|  Item 4  |    3     |          |    3     |
|  Item 5  |          |    1     |          |
|  Item 8  |          |          |    1     |