嵌套哈希上的Sum元素

时间:2014-10-29 21:42:30

标签: ruby hash

我正在使用MongoDB来存储聚合信息。类似于以下哈希的东西我们可以看到有多少客户按性别,年龄和地区对它们进行分组(实际数据结构有5个级别):

customers = {
  male: {
    young: {
      european: 1, 
      american: 2,
    },
    adult: {
      european: 3,
      american: 4,
    },
    senior: {
      european: 5,
      american: 6,
    }
  },
  female: {
    young: {
      european: 7,
      american: 8,
    },
    adult: {
      european: 9,
      american: 10,
    },
    senior: {
      european: 11,
      american: 12
    }
  }
}

商务人士喜欢访问所有信息。考虑到这一点,我正在尝试编写一个接收这样的哈希的方法,一个嵌套级别的数组和他们想要查询的嵌套属性,以返回该类型的客户的数量。

示例:如果我们想要检索年轻客户的数量,样板应该是这样的:

levels = %i(gender age region)
young_custumers = sum_method(customers, levels, {age: :young})

这应该会回报年轻客户的数量:18

任何人都知道这样做的优雅方式吗?

1 个答案:

答案 0 :(得分:1)

这是您可能希望考虑的方法。

<强>代码

def sum_em(h, filter)
  f = filter.first
  f = h.keys if f == :all
  if h[f.first].is_a? Hash
     f.reduce(0) { |t,k| t+sum_em(h[k], filter.drop(1)) } 
  else
     f.reduce(0) { |t,k| t+h[k] }
  end
end

<强>实施例

这些示例适用于您的哈希customers

sum_em customers, [:all,      [:young],         :all]        #=> 18
sum_em customers, [[:male],   [:young],         :all]        #=>  3
sum_em customers, [[:female], [:young],         :all]        #=> 15
sum_em customers, [:all,      [:young, :adult], [:american]] #=> 24
sum_em customers, [:all,      :all,             [:american]] #=> 42
sum_em customers, [:all,      :all,             :all]        #=> 78

这当然适用于任何级别。