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:
>>
>> [
>> =A0 =A0 =A0 ["A", "a", 1]
>> =A0 =A0 =A0 ["A", "b", 2]
>> =A0 =A0 =A0 ["B", "a", 1]
>>
>> ]
>>
>> into a hash as follow:
>> {
>> =A0 =A0 =A0 {"A" =3D> {"a" =3D> 1, "b" =3D> 2}},
>> =A0 =A0 =A0 {"B" =3D> {"a" =3D> 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.
>
> =A0a =3D [
> =A0 =A0["A", "a", 1],
> =A0 =A0["A", "b", 2],
> =A0 =A0["B", "a", 1]
> =A0]
>
> def a_to_h(a)
> =A0h=3D{}
> =A0a.map do |nested|
> =A0 =A0key =3D nested.shift
> =A0 =A0h[key] ||=3D {}
> =A0 =A0h[key].merge!({ nested.shift =3D> nested.shift })
> =A0end
> =A0h
> end
>
> irb:0> a_to_h(a)
> =3D> {"A"=3D>{"a"=3D>1, "b"=3D>2}, "B"=3D>{"a"=3D>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] ||=3D {})[k2] =3D v
irb(main):026:1>   h
irb(main):027:1> end
=3D> {"A"=3D>{"a"=3D>1, "b"=3D>2}, "B"=3D>{"a"=3D>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]=3DHash.new(&h.default_proc)}) do |h,(k1,k2,v)|
irb(main):034:1*   h[k1][k2] =3D v
irb(main):035:1>   h
irb(main):036:1> end
=3D> {"A"=3D>{"a"=3D>1, "b"=3D>2}, "B"=3D>{"a"=3D>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

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