我有一个对象数组,这些对象已根据这些对象的几个属性进行了排序。按优先顺序,这些属性为foo
,bar
和baz
。这意味着对象首先按foo
排序;那么具有相同foo
值的子序列按bar
排序;然后具有相同foo
和bar
值的那些按baz
排序。
我想将其转换为反映此分组的嵌套哈希。基本上我正在寻找一个递归的Enumerable#group_by
。键值为foo
,bar
和baz
;值可以是子哈希值,也可以是对象的数组。这是一个例子:
[obj1, obj2, ... objn].group_by_recursive(:foo, :bar, :baz)
#=> {
foo_val_1 => {
bar_val_1 => {
baz_val_1 => [
obj1,
obj2,
obj3
],
baz_val_2 => [
obj4,
obj5
]
},
bar_val_2 => {
baz_val_1 => [
obj6,
obj7
],
baz_val_2 => [
obj8
]
},
},
foo_val_2 => {
...
},
...
}
答案 0 :(得分:11)
提出了一个非常好的解决方案。像这样的猴子补丁Enumerable
:
module Enumerable
def group_by_recursive(*props)
groups = group_by(&props.first)
if props.count == 1
groups
else
groups.merge(groups) do |group, elements|
elements.group_by_recursive(*props.drop(1))
end
end
end
end
您传递的属性可以是Procs
或Symbols
答案 1 :(得分:1)
与Sean相似,缺乏错误处理......
class Array
def nested_group_by(*keys)
return self if keys.length == 0
groups = group_by(&keys.shift)
Hash[groups.map { | k, v | [k, v.nested_group_by(*keys)] }]
end
end