[英]combine keys in array of hashes
I map results of my query to create an array of hashes grouped by organisation_id
like so: 我映射查询结果以创建按organisation_id
分组的哈希数组,如下所示:
results.map do |i|
{
i['organisation_id'] => {
name: capability.name,
tags: capability.tag_list,
organisation_id: i['organisation_id'],
scores: {i['location_id'] => i['score']}
}
}
a capability
is defined outside the map. 在地图外部定义capability
。
The result looks like: 结果看起来像:
[{1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{26=>4}}}, {1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{12=>5}}}, {2 => {...}}...]
For every organisation_id
there is a separate entry in the array. 对于每个organisation_id
,数组中都有一个单独的条目。 I would like to merge these hashes and combine the scores
key as so: 我想合并这些散列并按如下方式结合scores
键:
[{1=>{:name=>"cap1", :tags=>["tag A"], :scores=>{26=>4, 12=>5}}}, {2=>{...}}... ]
To create the results
I use the following AR: 要创建results
我使用以下AR:
Valuation.joins(:membership)
.where(capability: capability)
.select("valuations.id, valuations.score, valuations.capability_id, valuations.membership_id, memberships.location_id, memberships.organisation_id")
.map(&:serializable_hash)
A Valuation
model: Valuation
模型:
class Valuation < ApplicationRecord
belongs_to :membership
belongs_to :capability
end
A Membership
model: Membership
模式:
class Membership < ApplicationRecord
belongs_to :organisation
belongs_to :location
has_many :valuations
end
results
snippet: results
片段:
[{"id"=>1, "score"=>4, "capability_id"=>1, "membership_id"=>1, "location_id"=>26, "organisation_id"=>1}, {"id"=>16, "score"=>3, "capability_id"=>1, "membership_id"=>2, "location_id"=>36, "organisation_id"=>1}, {"id"=>31, "score"=>3, "capability_id"=>1, "membership_id"=>3, "location_id"=>26, "organisation_id"=>2}, {"id"=>46, "score"=>6, "capability_id"=>1, "membership_id"=>4, "location_id"=>16, "organisation_id"=>2}...
I'll assume for each organization: the name, taglist and organization_id remains the same. 我假设每个组织:名称,标签列表和organization_id保持不变。
your_hash = results.reduce({}) do |h, i|
org_id = i['organisation_id']
h[org_id] ||= {
name: capability.name,
tags: capability.taglist,
organisation_id: org_id,
scores: {}
}
h[org_id][:scores][i['location_id']] = i['score']
# If the location scores are not strictly exclusive, you can also just +=
h
end
I believe this works, but data is needed to test it. 我相信这可行,但是需要数据来对其进行测试。
results.each_with_object({}) do |i,h|
h.update(i['organisation_id'] => {
name: capability.name,
tags: capability.tag_list,
organisation_id: i['organisation_id'],
scores: {i['location_id'] => i['score']}) { |_,o,n|
o[:scores].update(n[:score]); o }
}
end.values
This uses the form of Hash#update (aka merge!
) that uses a block to determine the values of keys that are present in both hashes being merged. 这使用Hash#update的形式(又名merge!
),该形式使用一个块来确定要合并的两个哈希中存在的键的值。 Please consult the doc for the contents of each of the block variables _
, o
and n
. 请查阅文档以获取每个块变量_
, o
和n
。
Assume, that result
is your final array of hashes: 假设, result
就是您的最终哈希数组:
result.each_with_object({}) do |e, obj|
k, v = e.flatten
if obj[k]
obj[k][:scores] = obj[k][:scores].merge(v[:scores])
else
obj[k] = v
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.