首页 > 解决方案 > 转换哈希数组的输入序列并通过葡萄实体表示

问题描述

这是一个两部分的问题

activerecord/Rails 的新手。一旦我执行下面的 activerecord 查询,我得到

results = A.joins(:b).group(:id, :status).count

这个结果,现在我想通过对来自的输出进行后处理来使用实体呈现结果

{[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}

[{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ]

(在预期输出的第二个哈希中,我添加了action1 => 0and action2 => 0,因为 0 应该是默认值。)

如何实现上述输出?我不确定是否可以在不进行后处理的情况下呈现查询的输出。到目前为止我试过

summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}

需要对上面的 map-reduce 代码进行更改以获得预期的结果。

预期的响应应该如下所示,因此我专注于对查询的输出进行后处理。

[
 { 'id' => value
   'action1' => count,
   'action1' => count,
   'action1' => count
 },
 {
  # same structure as above
 }
]

例如,我试图公开 rails 控制台中的 id 字段但遇到错误

class klassEntity < Grape::Entity
  expose :id
end

当我尝试

klassEntity.represent([{'id' => 1, 'action1' => 2, 'action2' => 2, 'action3' => 1}, {'id'=>2, 'action3' => 2, 'action1' => 0, 'action2' => 0} ])

这失败了(Object doesn't support #inspect) 我做错了什么?

更新

我通过从当前输出构造一个数组列表来完成这项工作

summaries.map {|k,v| {k[0] => {k[1] => v}}}.reduce {|acc, h| (acc || {}).deep_merge(h)}

每个数组元素都包含一个符号哈希。这也适用于 Rails 控制台。我想知道是否有到达这里的最佳方式。

标签: ruby-on-railsrubygrape-entity

解决方案


在此处找到仅使用标准库的选项。

我正在使用map但对象(Enumerator#with_object),其中对象是一个Hash#new,并带有一个块来获取一个空hash作为调用Hash#merge 的值!在上面:

summaries = {[1, "action1"]=>2, [1, "action2"]=>2, [1, "action3"]=>1, [2, "action3"]=>2}

summaries.map.with_object(Hash.new {|h, k| h[k] = {}}){|(v, k), h| h[v.first].merge!({v.last => k})}

结果:

#=> {1=>{"action1"=>2, "action2"=>2, "action3"=>1}, 2=>{"action3"=>2}}

推荐阅读