我正在执行一个活动记录命令 Product.pluck(:category_id,:price),它返回一个包含2个元素数组的数组:
[
[1, 500],
[1, 100],
[2, 300]
]
我想在第一个元素的基础上进行分组,创建一个看起来像的哈希:
{1 => [500, 100], 2 => [300]}
group_by似乎合乎逻辑,但复制了整个数组。即 a.group_by(&:first)产生:
{1=>[[1, 500], [1, 100]], 2=>[[2, 300]]}
答案 0 :(得分:13)
您可以对其进行二次转换:
Hash[
array.group_by(&:first).collect do |key, values|
[ key, values.collect { |v| v[1] } ]
end
]
或者直接绘制逻辑:
array.each_with_object({ }) do |item, result|
(result[item[0]] ||= [ ]) << item[1]
end
答案 1 :(得分:3)
由于您按第一个元素进行分组,只需将其与shift
一起删除,然后将结果转换为哈希:
array.group_by(&:first).map do |key, value|
value = value.flat_map { |x| x.shift; x }
[key, value]
end #=> {1=>[500, 100], 2=>[300]}
答案 2 :(得分:2)
这个单行似乎对我有用。
content
答案 3 :(得分:1)
我不喜欢破坏性的操作。
array.group_by(&:first).map { |id, a| [id, a.map(&:last)] }.to_h
答案 4 :(得分:0)
在我的应用中多次使用此功能,为阵列添加了扩展名:
# config/initializers/array_ext.rb
class Array
# given an array of two-element arrays groups second element by first element, eg:
# [[1, 2], [1, 3], [2, 4]].group_second_by_first #=> {1 => [2, 3], 2 => [4]}
def group_second_by_first
each_with_object({}) { |(first, second), h| (h[first] ||= []) << second }
end
end