在哈希单行中加入公共密钥

时间:2022-11-02 22:32:08

I have this array of pairs:

我有这对数组:

[{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]

I would like a method to merge the keys in common with multiple values to:

我想要一种方法将多个值共同的键合并到:

[{"a"=>["1","3","5"]}, {"b"=>["2","4"]}]

5 个解决方案

#1


4  

Improved following Marc-Andre's suggestion.

改进了Marc-Andre的建议。

array = [{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]
array.group_by(&:keys).map{|k, v| {k.first => v.flat_map(&:values)}}

Or

要么

array.group_by{|h| h.keys.first}.each_value{|a| a.map!{|h| h.values.first}}

#2


1  

Haven't tried it yet, but something like that should also works

尚未尝试过,但类似的东西也应该有效

   a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) do |x, hash|
      hash[x.keys.first] << x.values.first
   end

edit: For a one liner, and the same output :

编辑:对于一个班轮,并输出相同的:

[a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) { |x, hash| hash[x.keys.first] << x.values.first }]

#3


1  

A solution to your problem:

解决您的问题:

array.map(&:first).group_by(&:first).map{|k, v| {k => v.map(&:last)}}

I'm curious as to why you start and end with hashes containing only one key-pair. Arrays would be better suited. E.g.:

我很好奇为什么你开始和结束只包含一个密钥对的哈希。数组更适合。例如。:

other = [["a", "1"], ["b", "2"], ["a", "3"], ["b", "4"], ["a", "5"]]
r = other.group_by(&:first).map{|k, v| [k => v.map(&:last)]}
r  # => [["a", ["1", "3", "5"]], ["b", ["2", "4"]]]
Hash[r] # => {"a"=>["1", "3", "5"], "b"=>["2", "4"]}

#4


0  

array = [{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]
{}.tap{ |r| array.each{ |h| h.each{ |k,v| (r[k]||=[]) << v } } }

#5


0  

Not sure if you're giving out awards for brevity, but I like this way. The merge function with a block is ideally suited for this:

不确定你是否为了简洁而颁奖,但我喜欢这样。带块的合并功能非常适合这种情况:

new = {}
array.each {|p| new.merge!(p) {|k,l,r| [l,r].flatten }}

#1


4  

Improved following Marc-Andre's suggestion.

改进了Marc-Andre的建议。

array = [{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]
array.group_by(&:keys).map{|k, v| {k.first => v.flat_map(&:values)}}

Or

要么

array.group_by{|h| h.keys.first}.each_value{|a| a.map!{|h| h.values.first}}

#2


1  

Haven't tried it yet, but something like that should also works

尚未尝试过,但类似的东西也应该有效

   a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) do |x, hash|
      hash[x.keys.first] << x.values.first
   end

edit: For a one liner, and the same output :

编辑:对于一个班轮,并输出相同的:

[a.each_with_object( Hash.new{ |h,k| h[k] = [] } ) { |x, hash| hash[x.keys.first] << x.values.first }]

#3


1  

A solution to your problem:

解决您的问题:

array.map(&:first).group_by(&:first).map{|k, v| {k => v.map(&:last)}}

I'm curious as to why you start and end with hashes containing only one key-pair. Arrays would be better suited. E.g.:

我很好奇为什么你开始和结束只包含一个密钥对的哈希。数组更适合。例如。:

other = [["a", "1"], ["b", "2"], ["a", "3"], ["b", "4"], ["a", "5"]]
r = other.group_by(&:first).map{|k, v| [k => v.map(&:last)]}
r  # => [["a", ["1", "3", "5"]], ["b", ["2", "4"]]]
Hash[r] # => {"a"=>["1", "3", "5"], "b"=>["2", "4"]}

#4


0  

array = [{"a"=>"1"}, {"b"=>"2"}, {"a"=>"3"}, {"b"=>"4"}, {"a"=>"5"}]
{}.tap{ |r| array.each{ |h| h.each{ |k,v| (r[k]||=[]) << v } } }

#5


0  

Not sure if you're giving out awards for brevity, but I like this way. The merge function with a block is ideally suited for this:

不确定你是否为了简洁而颁奖,但我喜欢这样。带块的合并功能非常适合这种情况:

new = {}
array.each {|p| new.merge!(p) {|k,l,r| [l,r].flatten }}