On Sun, Oct 24, 2010 at 11:27 AM, Sandor Szuecs
<sandor.szuecs / fu-berlin.de> 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.
>
>   >  ¢ ᢬ >  ¢ ⢬ >  ¢¢ ᢬ 
>  
>
> def a_to_h(a)
>  ½>  ®  
>   
>  
>  ݮ塨    
>  
>  
> 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

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/