Filling a hash from an enumerable


#1

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


#2

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”]


#3

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.


#4

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.


#5

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 :slight_smile:

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”>]}


#6

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”>}


#7

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. :wink:

Kind regards

robert


#8

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.


#9

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