Making hash key from arrays

Hi All,

I've two arrays,

keys = [300,300,301,301,301,302,302]

values = [1, 2, 1, 3, 4, 3, 4]

both the arrays have equal size.

I need to create a hask

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

Could any one please put the ruby code for this.

Cheers
A

···

--
Posted via http://www.ruby-forum.com/.

hsh = Hash.new{|h,k| h[k]=}
keys.zip(values).each{|k,v| hsh[k] << v}

···

On Mon, 7 Feb 2011 20:47:45 +0900, Arihan Sinha wrote:

Hi All,

I've two arrays,

keys = [300,300,301,301,301,302,302]

values = [1, 2, 1, 3, 4, 3, 4]

both the arrays have equal size.

I need to create a hask

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

Could any one please put the ruby code for this.

Cheers
A

--
Alex Gutteridge

Thanks for this but I am getting like

[[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]

but I actually need like

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

any help

···

--
Posted via http://www.ruby-forum.com/.

its working ok. my aplogies cheers

···

--
Posted via http://www.ruby-forum.com/.

just joining the fun here.. an inject version

keys.zip(values).inject(Hash.new{|h,k|h[k]=}) {|hsh,(k,v)|
hsh.tap{|h|h[k] << v}}
#=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

or

keys.zip(values).inject2(Hash.new{|h,k|h[k]=}) {|h,(k,v)| h[k] << v}
#=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

best regards -botp

···

On Mon, Feb 7, 2011 at 7:47 PM, Arihan Sinha <arihan_sinha@yahoo.com> wrote:

keys = [300,300,301,301,301,302,302]
values = [1, 2, 1, 3, 4, 3, 4]
hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

Thanks for this but I am getting like

[[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]

but I actually need like

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

any help

In ruby 1.9's irb:

ratdog:~ mike$ irb
>> keys = [300,300,301,301,301,302,302]
=> [300, 300, 301, 301, 301, 302, 302]
>> values = [1, 2, 1, 3, 4, 3, 4]
=> [1, 2, 1, 3, 4, 3, 4]
>> hsh = Hash.new{ |h, k| h[k] = }
=> {}
>> keys.zip(values) { |k, v| hsh[k] << v }
=> nil
>> hsh
=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

Mike

- --

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

···

On Feb 7, 2011, at 7:12 AM, Arihan Sinha wrote:

Thanks for this but I am getting like

[[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]

???

irb(main):004:0> hsh = Hash.new{|h,k| h[k]=}
=> {}
irb(main):005:0> keys.zip(values).each{|k,v| hsh[k] << v}
=> [[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]
irb(main):006:0> hsh
=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

but I actually need like

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

Btw, #zip without #each is more efficient:

irb(main):007:0> hsh = Hash.new{|h,k| h[k]=}
=> {}
irb(main):008:0> keys.zip(values) {|k,v| hsh[k] << v}
=> nil
irb(main):009:0> hsh
=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

Cheers

robert

···

On Mon, Feb 7, 2011 at 1:12 PM, Arihan Sinha <arihan_sinha@yahoo.com> wrote:

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

botp wrote in post #980085:

just joining the fun here.. an inject version

keys.zip(values).inject(Hash.new{|h,k|h[k]=}) {|hsh,(k,v)|
hsh.tap{|h|h[k] << v}}
#=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

That's a prime example of using inject purely for obfuscation.

The principal property of inject is that the value which is the output
of one iteration is fed in as in input to the next iteration. You're not
using that property here, because you're mutating the same object each
time. In that case, it's just a complicated way of saying 'each'. You
may as well just write:

h = Hash.new { |h,k| h[k] = }
keys.zip(values).each { |k,v| h[k] << v }
h

Furthermore, if you insist on using #tap, at least do it on the outside
where it belongs in this case:

Hash.new { |h,k| h[k] = }.tap do |hsh|
  keys.zip(values).each { |k,v| hsh[k] << v }
end

Now, if you wanted to do this in a functional way using inject, then you
would mutate nothing and instead build a new Hash object in each
iteration:

keys.zip(values).inject({}) do |hsh,(k,v)|
  if hsh.has_key?(k)
    hsh.merge(k=>hsh[k]+[v])
  else
    hsh.merge(k=>[v])
  end
end

That, in my opinion, is the correct way to use inject here - and it's
reasonably clear when written that way too. The Ruby runtime will end up
doing a lot of hash copying though.

Regards,

Brian.

···

--
Posted via http://www.ruby-forum.com/\.

Thanks, I never knew #zip took a block argument before.

···

On Mon, 7 Feb 2011 21:28:21 +0900, Robert Klemme wrote:

On Mon, Feb 7, 2011 at 1:12 PM, Arihan Sinha <arihan_sinha@yahoo.com> > wrote:

Thanks for this but I am getting like

[[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]

???

irb(main):004:0> hsh = Hash.new{|h,k| h[k]=}
=> {}
irb(main):005:0> keys.zip(values).each{|k,v| hsh[k] << v}
=> [[300, 1], [300, 2], [301, 1], [301, 3], [301, 4], [302, 3], [302, 4]]
irb(main):006:0> hsh
=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

but I actually need like

hsh = {"300" =>["1","2"],"301" => ["1","3","4"],"302"=>["3","4"]}

Btw, #zip without #each is more efficient:

irb(main):007:0> hsh = Hash.new{|h,k| h[k]=}
=> {}
irb(main):008:0> keys.zip(values) {|k,v| hsh[k] << v}
=> nil
irb(main):009:0> hsh
=> {300=>[1, 2], 301=>[1, 3, 4], 302=>[3, 4]}

Cheers

robert

--
Alex Gutteridge

i agree that we disagree :slight_smile:

best regards -botp

···

on Wed, Feb 9, 2011 at 4:01 AM, Brian Candler <b.candler@pobox.com> wrote:

<snip>.. That, in my opinion, is the correct way to use inject here...

IIRC that was introduced later. If my memory does not fail me
originally Array#zip only returned an Array and block handling (as
well as multiple Array arguments to Array#zip) were added later.

Kind regards

robert

···

On Mon, Feb 7, 2011 at 1:43 PM, Alex Gutteridge <alexg@ruggedtextile.com> wrote:

Thanks, I never knew #zip took a block argument before.

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