在Ruby 2.3和2.0中(没有
transform_values
,使用
group_by
):
a = {'name' => 200, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'web'}
b = {'name' => 201, 'segment' => 'shared', 'dc' => 'nyc', 'designation' => 'generic'}
c = {'name' => 202, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'app'}
d = {'name' => 400, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'web'}
e = {'name' => 401, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'web'}
f = {'name' => 402, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'app'}
g = {'name' => 403, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'app'}
members = [a,b,c,d,e,f,g]
h1 = members.group_by { | gr | gr['segment'] }
p h1
h1.each { | k1, v1 | h1[k1] = v1.group_by { | gr | gr['dc'] } }
puts
p h1
h1.each { | k1, v1 | v1.each { | k2, v2 | v1[k2] = v2.group_by { | gr | gr['designation'] } } }
puts
p h1
h1.each { | k1, v1 | v1.each { | k2, v2 | v2.each { | k3, v3 | v2[k3] = v3.collect { | el | el['name'] } } } }
puts '--- final result ---'
p h1
也许在没有使用
group_by
的Ruby 1.8版本中:
a = {'name' => 200, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'web'}
b = {'name' => 201, 'segment' => 'shared', 'dc' => 'nyc', 'designation' => 'generic'}
c = {'name' => 202, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'app'}
d = {'name' => 400, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'web'}
e = {'name' => 401, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'web'}
f = {'name' => 402, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'app'}
g = {'name' => 403, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'app'}
members = [a,b,c,d,e,f,g]
puts '=== without group_by ==='
class Array
def groupedByKey(p_key)
new_h = {}
self.each do | el |
key = el[p_key]
unless new_h[key]
then
new_h[key] = [el]
else
new_h[key] << el
end
end
new_h
end
end
h1 = members.groupedByKey('segment')
p h1
h1.each { | k1, v1 | h1[k1] = v1.groupedByKey('dc') }
puts
p h1
h1.each { | k1, v1 | v1.each { | k2, v2 | v1[k2] = v2.groupedByKey('designation') } }
puts
p h1
h1.each { | k1, v1 | v1.each { | k2, v2 | v2.each { | k3, v3 | v2[k3] = v3.collect { | el | el['name'] } } } }
puts '--- final result ---'
p h1
执行(在2.0中):
$ ruby -w t2.rb
=== without group_by ===
{"alpha"=>[{"name"=>200, "segment"=>"alpha", "dc"=>"nye",
...
--- final result ---
{"alpha"=>{"nyc"=>{"web"=>[200], "app"=>[202]}, "sfc"=>{"web"=>[400], "app"=>[403]}},
"shared"=>{"nyc"=>{"generic"=>[201]}, "sfc"=>{"web"=>[401], "app"=>`[402]}}}
编辑
结合Cary的Hash#transform_values
:
a = {'name' => 200, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'web'}
b = {'name' => 201, 'segment' => 'shared', 'dc' => 'nyc', 'designation' => 'generic'}
c = {'name' => 202, 'segment' => 'alpha', 'dc' => 'nyc', 'designation' => 'app'}
d = {'name' => 400, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'web'}
e = {'name' => 401, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'web'}
f = {'name' => 402, 'segment' => 'shared', 'dc' => 'sfc', 'designation' => 'app'}
g = {'name' => 403, 'segment' => 'alpha', 'dc' => 'sfc', 'designation' => 'app'}
members = [a,b,c,d,e,f,g]
puts '=== should work in Ruby 1.8 ==='
class Array
def groupedByKey(p_key)
new_h = {}
self.each do | el |
key = el[p_key]
unless new_h[key]
then
new_h[key] = [el]
else
new_h[key] << el
end
end
new_h
end
end
class Hash
def transformValues
Hash[self.collect { | k, v | [ k, yield(v) ] } ]
end
end
h1 = members.groupedByKey('segment')
puts '--- grouped by segment'
p h1
h2 = h1.transformValues { | v1 | v1.groupedByKey('dc') }
puts '--- grouped by dc'
p h2
h2 = members.groupedByKey('segment').
transformValues { | v1 | v1.groupedByKey('dc').
transformValues { | val | val.groupedByKey('designation') } }
puts '--- grouped by designation'
p h2
h2 = members.groupedByKey('segment').
transformValues { | v1 | v1.groupedByKey('dc').
transformValues { | v2 | v2.groupedByKey('designation').
transformValues { | v3 | v3.collect { | el | el['name'] } } } }
puts '--- final result ---'
p h2