Forum: Ruby Filling a hash from an enumerable

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Pete H. (Guest)
on 2008-10-09 05:03
(Received via mailing list)
Hi folks,

Given:

Person = Struct.new(:name,:age,:city)
people_array = [
    Person.new('bob',12,'SFO'),
    Person.new('dave',14,'NYC'),
    Person.new('jane',6,'LDN') ]

people_map = {}
people_array.each{ |p| people_map[p.name] = p }


Is there a cleaner way to build people_map? I'm thinking there might be
something like:

people_map = people_array.to_map{ |x| x.name }

in the standard library somewhere that I don't know of.

Thanks for any pointers,
Pete
Peña, Botp (Guest)
on 2008-10-09 05:42
(Received via mailing list)
From: Pete H. [mailto:removed_email_address@domain.invalid]
# people_map = people_array.to_map{ |x| x.name }

you should try it,

>> people_array.map{ |p| p.name }
=> ["bob", "dave", "jane"]
Thomas S. (Guest)
on 2008-10-09 06:56
(Received via mailing list)
On Oct 8, 9:00 pm, Pete H. <removed_email_address@domain.invalid> wrote:
> people_map = {}
> people_array.each{ |p| people_map[p.name] = p }
>
> Is there a cleaner way to build people_map? I'm thinking there might be
> something like:
>
> people_map = people_array.to_map{ |x| x.name }
>
> in the standard library somewhere that I don't know of.

Facets has #graph / #mash.

  require 'facets'

  people_array.graph{ |p| [p.name, p] }

  # or

  people_array.mash{ |p| [p.name, p] }

T.
Peña, Botp (Guest)
on 2008-10-09 07:09
(Received via mailing list)
From: Peña, Botp [mailto:removed_email_address@domain.invalid]
# >> people_array.map{ |p| p.name }
# => ["bob", "dave", "jane"]

pls ignore above, i'm still searching my lost brain :)

try #group_by,

> people_array.group_by{ |p| p.name }
=> {"bob"=>[#<struct Person name="bob", age=12, city="SFO">],
"dave"=>[#<struct Person name="dave", age=14, city="NYC">],
"jane"=>[#<struct Person name="jane", age=6, city="LDN">]}
Pete H. (Guest)
on 2008-10-09 11:13
(Received via mailing list)
Peña, Botp wrote:
>>
> => {"bob"=>[#<struct Person name="bob", age=12, city="SFO">], "dave"=>[#<struct Person 
name="dave", age=14, city="NYC">], "jane"=>[#<struct Person name="jane", age=6, 
city="LDN">]}
>
Thanks, but that's not quite what I wanted. It creates a hash whose
values are lonely arrays, rather than a map whose values are the structs
themselves.

I guess I'll just have to monkey-patch Enumerable with a to_map method.
Should probably figure out a better name first tho.
William J. (Guest)
on 2008-10-09 11:25
(Received via mailing list)
On Oct 8, 8:00 pm, Pete H. <removed_email_address@domain.invalid> wrote:
> people_map = {}
> Pete
Hash[ * people_array.map{|x| [ x.name, x ] }.flatten ]
    ==>{"dave" => #<struct Person name="dave", age=14, city="NYC">,
"jane" => #<struct Person name="jane", age=6, city="LDN">,
"bob" => #<struct Person name="bob", age=12, city="SFO">}
Robert K. (Guest)
on 2008-10-09 11:33
(Received via mailing list)
2008/10/9 William J. <removed_email_address@domain.invalid>:
>> something like:
> Hash[ * people_array.map{|x| [ x.name, x ] }.flatten ]
>    ==>{"dave" => #<struct Person name="dave", age=14, city="NYC">,
> "jane" => #<struct Person name="jane", age=6, city="LDN">,
> "bob" => #<struct Person name="bob", age=12, city="SFO">}

And since we did not have an inject version so far:

irb(main):001:0> require 'pp'
=> true
irb(main):002:0> Person = Struct.new(:name,:age,:city)
=> Person
irb(main):003:0> people_array = [
irb(main):004:1*   Person.new('bob',12,'SFO'),
irb(main):005:1*   Person.new('dave',14,'NYC'),
irb(main):006:1*   Person.new('jane',6,'LDN'),
irb(main):007:1* ]
=> [#<struct Person name="bob", age=12, city="SFO">, #<struct Person
name="dave", age=14, city="NYC">, #<struct Person name="jane", age=6,
city="LDN">]
irb(main):008:0> pp( people_map = people_array.inject({}) do |ha,pe|
irb(main):009:2*   ha[pe.name] = pe
irb(main):010:2>   ha
irb(main):011:2> end )
{"dave"=>#<struct Person name="dave", age=14, city="NYC">,
 "jane"=>#<struct Person name="jane", age=6, city="LDN">,
 "bob"=>#<struct Person name="bob", age=12, city="SFO">}
=> nil

Just for completeness reasons of course. ;-)

Kind regards

robert
Peña, Botp (Guest)
on 2008-10-09 13:38
(Received via mailing list)
From: Pete H. [mailto:removed_email_address@domain.invalid]
# Peña, Botp wrote:
# >> people_array.group_by{ |p| p.name }
# > => {"bob"=>[#<struct Person name="bob", age=12,
# city="SFO">], "dave"=>[#<struct Person name="dave", age=14,
# city="NYC">], "jane"=>[#<struct Person name="jane", age=6,
# city="LDN">]}
# >
# Thanks, but that's not quite what I wanted. It creates a hash whose
# values are lonely arrays,...

lonely indeed, but consider the case when you have dup names

kind regards -botp
Thomas S. (Guest)
on 2008-10-09 13:48
(Received via mailing list)
On Oct 9, 3:10 am, Pete H. <removed_email_address@domain.invalid> wrote:

> I guess I'll just have to monkey-patch Enumerable with a to_map method.
> Should probably figure out a better name first tho.

You mean like "map hash", aka "mash".

T.
This topic is locked and can not be replied to.