1

我有一个模型,我想将其分组为 2 列:

ModelName.group(:location_id, :referrer).count

这样做的结果是一个难以处理的对象:

{
    [ '1', 'friend' ] => 100,
    [ '1', 'family' ] => 23,
    [ '2', 'friend' ] => 43,
    [ '2', 'family' ] => 65
}

我想将这些值映射到更容易起诉的结构,但我无法让它发挥作用。理想情况下,它会是这样的:

{
    '1' => {
        'friend' => 100
        'family' => 23
    },
    '2' => {
        'friend' => 100
        'family' => 23
    }
}

我怎样才能做到这一点(最好它也适用于第三维)?

4

2 回答 2

2

您可以获取当前输出并按每个哈希键对其进行分组,然后转换哈希值:

data.group_by { |key, _| key.first }
    .transform_values do |values|
      values.each_with_object({}) do |(keys, value), hash|
        hash[keys.last] = value
      end
    end
# {"1"=>{"friend"=>100, "family"=>23}, "2"=>{"friend"=>43, "family"=>65}}
于 2020-02-13T21:55:01.583 回答
0

鉴于:

original = {
  [ '1', 'friend' ] => 100,
  [ '1', 'family' ] => 23,
  [ '2', 'friend' ] => 43,
  [ '2', 'family' ] => 65
}

您可以通过结合自动生成哈希来很好地到达那里:

desired = Hash.new { |h, k| h[k] = { } }

和一些嵌套的破坏:

original.each_with_object(desired) do |((loc, ref), n), h|
  h[loc][ref] = n
end
desired
# {"1"=>{"friend"=>100, "family"=>23}, "2"=>{"friend"=>43, "family"=>65}}

或者,如果您不喜欢预先声明desired

desired = original.each_with_object(Hash.new { |h, k| h[k] = { } }) do |((loc, ref), n), h|
  h[loc][ref] = n
end
# {"1"=>{"friend"=>100, "family"=>23}, "2"=>{"friend"=>43, "family"=>65}}

也许:

reorg   = ->(((loc, ref), n), h) { h[loc][ref] = n }
desired = original.each_with_object(Hash.new { |h, k| h[k] = { } }, &reorg)
# {"1"=>{"friend"=>100, "family"=>23}, "2"=>{"friend"=>43, "family"=>65}}
于 2020-02-14T07:13:10.020 回答