我有如下的ruby数组:
array = [{"id"=>8, "book_id"=>14238}, {"id"=>5, "book_id"=>14238}, {"id"=>7, "book_id"=>10743}, {"id"=>9, "book_id"=>10743}]
我想要一个新的数组,结合ids
具有相同book_id
的结果。
预期结果:
array = [{"book_id"=>14238, "id"=>[8,5]}, {"book_id"=>10743, "id"=>[7,9]}]
答案 0 :(得分:2)
我不能说这很容易理解,但它很简洁:
array.group_by {|item| item["book_id"] }.map do |k, v|
{ "book_id" => k, "id" => v.map {|item| item["id"] } }
end
=> [{"book_id"=>14238, "id"=>[8, 5]}, {"book_id"=>10743, "id"=>[7, 9]}]
由group_by
完成的第一次转化会重新排列您的数组,以便将具有相同book_id
的项目组合在一起:
array.group_by {|item| item["book_id"] }
=> {14238=>[{"id"=>8, "book_id"=>14238}, {"id"=>5, "book_id"=>14238}], 10743=>[{"id"=>7, "book_id"=>10743}, {"id"=>9, "book_id"=>10743}]}
第二个转换(map
)将group_by生成的哈希重新格式化为哈希列表,第二个map
将id收集到列表中。
答案 1 :(得分:1)
您也可以使用Hash#update(a.k.a。merge!
)的形式执行此操作,该格式使用块来解析合并后的两个哈希中包含的键的值。
<强>代码强>
def aggregate(arr)
arr.each_with_object({}) do |g,h|
f = { g["book_id"]=>{ "id"=>[g["id"]], "book_id"=>g["book_id"] } }
h.update(f) do |_,ov,nv|
ov["id"] << nv["id"].first
ov
end
end.values
end
示例强>
arr = [{"id"=>8, "book_id"=>14238}, {"id"=>5, "book_id"=>14238},
{"id"=>7, "book_id"=>10743}, {"id"=>9, "book_id"=>10743},
{"id"=>6, "book_id"=>10511}]
aggregate(arr)
#=> [{"id"=>[8, 5], "book_id"=>14238},
# {"id"=>[7, 9], "book_id"=>10743},
# {"id"=>[6], "book_id"=>10511}]
替代输出
根据您的要求,您可以考虑构建单个哈希而不是另一个哈希数组:
def aggregate(arr)
arr.each_with_object({}) { |g,h|
h.update({ g["book_id"]=>[g["id"]] }) { |_,ov,nv| ov+nv } }
end
aggregate(arr)
#=> {14238=>[8, 5], 10743=>[7, 9], 10511=>[6]}
答案 2 :(得分:0)
我为输出使用哈希以便于查找和/或重用:
array = [{"id"=>8, "book_id"=>14238}, {"id"=>5, "book_id"=>14238}, {"id"=>7, "book_id"=>10743}, {"id"=>9, "book_id"=>10743}]
hash = array.group_by{ |h| h['book_id'] }.map{ |k, v| [k, v.flat_map{ |h| h['id'] }]}.to_h
# => {14238=>[8, 5], 10743=>[7, 9]}
键是book_id
值,关联的数组包含id
值。
的预期结果
array = [{"book_id"=>14238, "id"=>[8,5]}, {"book_id"=>10743, "id"=>[7,9]}]
如果你要在其中进行任何类型的查找,不是一个好的结构。想象一下,有数百或数千个元素需要在数组中找到"book_id" == 10743
,特别是如果它不是一个排序列表;必须走这个数组,直到找到所需的条目。这是一个缓慢的过程。
相反,将结构简化为简单的哈希,允许您使用简单的哈希查找轻松找到值:
hash[10743]
查找永远不会减慢。
如果要通过排序按顺序迭代结果数据,请使用
sorted_keys = hash.keys.sort
和
hash.values_at(*sorted_keys)
以排序顺序提取值。如果需要提取键/值,则迭代哈希,也许是为了插入数据库。