Reputation: 7605
I have a hash that contains a number of keys/values that need sorting by their deepest value.
Here is an example of what I am dealing with:
hash = {"en"=>
{ "key1"=>
{"foo1"=>1,
"foo2"=>2,
"foo3"=>1},
"key2"=>
{"foo4"=>1,
"foo5"=>3,
"foo6"=>2,
"foo7"=>1}
}
"fr"=>
....
}
I want to key each main key (i.e. "en", "fr", es") and sort by the values for the keys within. So having "en" and for "key1" to have "value2" at the top with the highest number (frequency). Then doing the same for the rest of the hash. I'm not bothered about the order of the keys "en", "fr" etc.
So I want the output to be something like this:
hash = {"en"=>
{ "key1"=>
{"foo2"=>2,
"foo1"=>1,
"foo3"=>1},
"key2"=>
{"foo5"=>3,
"foo6"=>2,
"foo4"=>1,
"foo7"=>1}
}
"fr"=>
....
}
Upvotes: 2
Views: 165
Reputation: 303520
Fragile, but should work:
def sort_deep(h)
if h.values.all?{ |o| o.is_a? Numeric }
Hash[ h.sort_by{|k,v|[-v,k]} ]
else
Hash[ h.map{ |k,v| [ k, sort_deep(v) ] } ]
end
end
Proof:
hash = {"en"=>
{ "key1"=>
{"foo1"=>1,
"foo2"=>2,
"foo3"=>1},
"key2"=>
{"foo4"=>1,
"foo5"=>3,
"foo6"=>2,
"foo7"=>1}
},
"fr"=>
{ "key1"=>
{"foo1"=>91,
"foo2"=>22,
"foo3"=>12},
"key2"=>
{"foo4"=>21,
"foo5"=>31,
"foo6"=>27,
"foo7"=>11}
}
}
require 'pp'
pp sort_deep(hash)
#=> {"en"=>
#=> {"key1"=>{"foo2"=>2, "foo1"=>1, "foo3"=>1},
#=> "key2"=>{"foo5"=>3, "foo6"=>2, "foo4"=>1, "foo7"=>1}},
#=> "fr"=>
#=> {"key1"=>{"foo1"=>91, "foo2"=>22, "foo3"=>12},
#=> "key2"=>{"foo5"=>31, "foo6"=>27, "foo4"=>21, "foo7"=>11}}}
Upvotes: 2