ルビー2.3
及び2.0(group_by
と、transform_values
なし):
ルビー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]
h1 = members.group_by { | gr | gr['segment'] }
p h1
# in h1 at key k1 put this new value
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
なし):
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 # reopen class Array
def groupedByKey(p_key)
new_h = {}
self.each do | el | # el must be a hash
key = el[p_key]
unless new_h[key]
then # the key does not exist, create a key - value pair
new_h[key] = [el] # the value is an array with the whole element
else # a key and value already exist ...
new_h[key] << el # ... push the new value onto the array
end
end
new_h
end
end # class Array
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)0
実行:ケーリーのHash#transform_values
と組み合わせる
$ 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]}}}
EDIT:
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 # reopen class Array
def groupedByKey(p_key)
new_h = {}
self.each do | el | # el must be a hash
key = el[p_key]
unless new_h[key]
then # the key does not exist, create a key - value pair
new_h[key] = [el] # the value is an array with the whole element
else # a key and value already exist ...
new_h[key] << el # ... push the new value onto the array
end
end
new_h
end
end # class Array
class Hash
def transformValues
Hash[self.collect { | k, v | [ k, yield(v) ] } ]
end
end
# Step by step
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
# One step.
# Note that the hash returned by each groupedByKey is immediately transformed
# (watch the dot after groupedByKey('xxx')).
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
申し訳ありませんが、私が期待される出力の一部を理解していません。たとえば: ':alpha - >:nyc - >:app'のようになります。このトリプレットを持つメンバーはいませんが、どこから来たのですか? 'ヌル'はどう? 'ジェネリック'はどうですか? – tokland
@tokland携帯電話からの私の謝罪、コピー&ペーストの問題と混在物。いいキャッチ!それは今はっきりしていますか? – ARL
'dict'とは何ですか?それは空のハッシュとして始まりますか? – hoffm