On Oct 24, 2010, at 7:07 PM, Robert Klemme wrote:
On Oct 24, 2010, at 7:25 AM, Zhi-Qiang Lei wrote:
Dear All,
I'm seeking a method to convert an array like:
[
["A", "a", 1]
["A", "b", 2]
["B", "a", 1]
]
into a hash as follow:
{
{"A" => {"a" => 1, "b" => 2}},
{"B" => {"a" => 1}}
}
Do you have any idea on this? Thanks in advance.
I don't think that you really want to add 3 layers of dictionary.
If you really want this, then you think about your abstractions to
get a simpler solution.
a = [
["A", "a", 1],
["A", "b", 2],
["B", "a", 1]
]
def a_to_h(a)
h={}
a.map do |nested|
key = nested.shift
h[key] ||= {}
h[key].merge!({ nested.shift => nested.shift })
end
h
end
irb:0> a_to_h(a)
=> {"A"=>{"a"=>1, "b"=>2}, "B"=>{"a"=>1}}
Here's another way:
irb(main):019:0> [
irb(main):020:1* ["A", "a", 1],
irb(main):021:1* ["A", "b", 2],
irb(main):022:1* ["B", "a", 1],
irb(main):023:1*
irb(main):024:1* ].inject({}) do |h,(k1,k2,v)|
irb(main):025:1* (h[k1] ||= {})[k2] = v
irb(main):026:1> h
irb(main):027:1> end
=> {"A"=>{"a"=>1, "b"=>2}, "B"=>{"a"=>1}}
and another one
irb(main):028:0> [
irb(main):029:1* ["A", "a", 1],
irb(main):030:1* ["A", "b", 2],
irb(main):031:1* ["B", "a", 1],
irb(main):032:1*
irb(main):033:1* ].inject(Hash.new {|h,k|
h[k]=Hash.new(&h.default_proc)}) do |h,(k1,k2,v)|
irb(main):034:1* h[k1][k2] = v
irb(main):035:1> h
irb(main):036:1> end
=> {"A"=>{"a"=>1, "b"=>2}, "B"=>{"a"=>1}}
But I totally agree: why build up a strcuture of nested Arrays and
then convert it into the nested Hash structure? Is is much more
efficient to build up the Hash structure initially. One might even
create a Struct for values in the top level Hash.
Cheers
robert