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.
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}}
All the best, Sandor Szücs
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.
--
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
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.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
endirb:0> a_to_h(a)
=> {"A"=>{"a"=>1, "b"=>2}, "B"=>{"a"=>1}}
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
A beautiful injecting, thank you all. Because an external library return the array, I have to do this.
On Oct 24, 2010, at 7:07 PM, Robert Klemme wrote:
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.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
endirb: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/
a = [ ["A", "a", 1],
["A", "b", 2],
["B", "a", 1] ]
h = Hash.new{|hash,key| hash[key] = {} }
a.each{|x,y,z| h[y] = z}
On Oct 24, 6:07 am, Robert Klemme <shortcut...@googlemail.com> wrote:
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}}
I'm sorry to bring this old topic out. But there is a question make me confused.
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}}
Is the tuple (k1, k2, v) in block arguments an array? What's the meaning of () in block arguments? Thanks.
Best regards,
Zhi-Qiang Lei
zhiqiang.lei@gmail.com
On Oct 24, 2010, at 7:07 PM, Robert Klemme wrote:
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.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
endirb: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/
A beautiful injecting
The first solution given is by far the more readable and more
understandable, compared to the injects, I find.
The inject() will pass two arguments to the block. The accumulated value and the new element. In the use of the parentheses in the block arguments acts like an array assignment so the individual values of the array element are available with more meaningful names.
.inject({}) do |h,array|
k1, k2, v = array
(h[k1] ||= {})[k2] = v
h
end
is the same thing without using the block's ability to "unpack" the array elements.
-Rob
Rob Biedenharn
Rob@AgileConsultingLLC.com http://AgileConsultingLLC.com/
rab@GaslightSoftware.com http://GaslightSoftware.com/
On Nov 5, 2010, at 10:58 AM, Zhi-Qiang Lei wrote:
On Oct 24, 2010, at 7:07 PM, Robert Klemme wrote:
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.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
endirb: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/I'm sorry to bring this old topic out. But there is a question make me confused.
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}}Is the tuple (k1, k2, v) in block arguments an array? What's the meaning of () in block arguments? Thanks.
Best regards,
Zhi-Qiang Lei
zhiqiang.lei@gmail.com
I agree.
On Oct 25, 2010, at 12:02 AM, Adam Prescott wrote:
A beautiful injecting
The first solution given is by far the more readable and more
understandable, compared to the injects, I find.