在第一个元素的基础上对数组进行分组,而不在Ruby中重复

时间:2014-10-28 19:46:53

标签: ruby arrays grouping

我正在执行一个活动记录命令 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]]}

5 个答案:

答案 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