Ruby Array group_by具有多个值的键

时间:2014-11-14 02:23:06

标签: ruby arrays hashtable

我有一个Ruby数组:

[
    {tags: [1,2]},
    {tags: [1,3]},
    {tags: [1,4]},
    {tags: [2,4]},
    {tags: [2,5]}
]

我需要按照标签对对象进行分组:

{
    1: [{tags: [1,2]}, {tags: [1,3]}, {tags: [1,4]}],
    2: [{tags: [1,2]}, {tags: [2,4]}, {tags: [2,5]}],
    3: [{tags: [1,3]}],
    4: [{tags: [1,4]}, {tags: [2,4]}],
    5: [{tags: [2,5]}]
}

有没有神奇的Ruby方法呢?

3 个答案:

答案 0 :(得分:4)

使用Enumerable#each_with_object

tags = [
  {tags: [1,2]},
  {tags: [1,3]},
  {tags: [1,4]},
  {tags: [2,4]},
  {tags: [2,5]}
]
tags.each_with_object(Hash.new { |h,k| h[k] = [] }) { |h, result|
  h[:tags].each { |n| result[n] << h }
}
# => {1=>[{:tags=>[1, 2]}, {:tags=>[1, 3]}, {:tags=>[1, 4]}],
#     2=>[{:tags=>[1, 2]}, {:tags=>[2, 4]}, {:tags=>[2, 5]}],
#     3=>[{:tags=>[1, 3]}],
#     4=>[{:tags=>[1, 4]}, {:tags=>[2, 4]}],
#     5=>[{:tags=>[2, 5]}]}

答案 1 :(得分:2)

我会做这样的事情:

array = [{tags: [1,2]}, {tags: [1,3]}, {tags: [1,4]}, {tags: [2,4]}, {tags: [2,5]}]

result = Hash.new { |hash, key| hash[key] = [] }

array.each do |tags|
  tags[:tags].each { |tag| result[tag] << tags }
end

puts result
#=> {1=>[{:tags=>[1, 2]}, {:tags=>[1, 3]}, {:tags=>[1, 4]}], 
#    2=>[{:tags=>[1, 2]}, {:tags=>[2, 4]}, {:tags=>[2, 5]}], 
#    3=>[{:tags=>[1, 3]}], 
#    4=>[{:tags=>[1, 4]}, {:tags=>[2, 4]}], 
#    5=>[{:tags=>[2, 5]}]}

答案 2 :(得分:1)

我建议如下:

tags.each_with_object({}) {|g,h| g.values.flatten.each {|i| (h[i]||=[]) << g}}
  #=> {1=>[{:tags=>[1, 2]}, {:tags=>[1, 3]}, {:tags=>[1, 4]}], 
  #    2=>[{:tags=>[1, 2]}, {:tags=>[2, 4]}, {:tags=>[2, 5]}],
  #    3=>[{:tags=>[1, 3]}],
  #    4=>[{:tags=>[1, 4]}, {:tags=>[2, 4]}],
  #    5=>[{:tags=>[2, 5]}]}