是否可以通过选择按键来实现:
例如
h = [
{a: 1, b: "Hello", c: "Test1"},
{a: 2, b: "Hey", c: "Test1"},
{a: 3, b: "Hi", c: "Test2"}
]
预期产量
[
{a: 1, b: "Hello, Hey", c: "Test1"}, # See here, I don't want key 'a' to be merged
{a: 3, b: "Hi", c: "Test2"}
]
我的尝试
g = h.group_by{|k| k[:c]}.values
OUTPUT =>
[
[
{:a=>1, :b=>"Hello", :c=>"Test1"},
{:a=>2, :b=>"Hey", :c=>"Test1"}
], [
{:a=>3, :b=>"Hi", :c=>"Test2"}
]
]
g.each do |v|
if v.length > 1
c = v.reduce({}) do |s, l|
s.merge(l) { |_, a, b| [a, b].uniq.join(", ") }
end
end
p c #{:a=>"1, 2", :b=>"Hello, Hey", :c=>"Test1"}
end
所以,我得到的输出是
{:a=>"1, 2", :b=>"Hello, Hey", :c=>"Test1"}
但是,我需要
{a: 1, b: "Hello, Hey", c: "Test1"}
注意::这只是我提出问题的HASH测试数组。但是,实际的哈希值有很多键。因此,请不要给出关键的比较答案
我需要一个不太复杂的解决方案
答案 0 :(得分:3)
我看不到您的代码的简单版本。要使其完全正常工作,您可以使用merge
块中的第一个参数,而不必在需要合并a
和b
或仅使用{{1 }}。您的行将变为:
a
答案 1 :(得分:1)
也许您可以考虑使用此选项,但是我不知道它是否那么简单:
h.group_by { |h| h[:c] }.values.map { |tmp| tmp[0].merge(*tmp[1..]) { |key, oldval, newval| key == :b ? [oldval, newval].join(' ') : oldval } }
#=> [{:a=>1, :b=>"Hello Hey", :c=>"Test1"}, {:a=>3, :b=>"Hi", :c=>"Test2"}]
第一部分按:c
h.group_by { |h| h[:c] }.values #=> [[{:a=>1, :b=>"Hello", :c=>"Test1"}, {:a=>2, :b=>"Hey", :c=>"Test1"}], [{:a=>3, :b=>"Hi", :c=>"Test2"}]]
然后它映射为使用Hash#merge
将第一个元素与其他元素合并答案 2 :(得分:1)
h.each_with_object({}) do |g,h|
h.update(g[:c]=>g) { |_,o,n| o.merge(b: "#{o[:b]}, #{n[:b]}") }
end.values
#=> [{:a=>1, :b=>"Hello, Hey", :c=>"Test1"},
# {:a=>3, :b=>"Hi", :c=>"Test2"}]
这使用Hash#update的形式,该形式采用一个块(此处为{ |_,o,n| o.merge(b: "#{o[:b]}, #{n[:b]}") }
)来确定两个合并的散列中存在的键的值。第一个块变量保存公用密钥。我对该变量使用了下划线,主要是为了向读者表明该变量未在块计算中使用。有关其他两个块变量的定义,请参阅文档。
请注意,values
的接收者等于。
h.each_with_object({}) do |g,h|
h.update(g[:c]=>g) { |_,o,n| o.merge(b: "#{o[:b]}, #{n[:b]}") }
end
#=> { “Test1”=>{:a=>1, :b=>"Hello, Hey", :c=>"Test1"},
# “Test2=>{:a=>3, :b=>"Hi", :c=>"Test2"} }