mapping an array to a hash?

N

Nick Woolley

Hi,

Can anyone suggest an idiomatic ruby equivalent to this perl snippet?

my %index = map { $_ => compute_something($_) } @files;

Where @files is an array of filenames, and compute_something is a
subroutine which does some probably expensive operation on the file.

The result is a hash indexing the file name to the computed result for
that file. This and it's grep equivalent is something I find quite
quite handy in perl.

The best I came up with so far seems reletively clunky to me:

index = Hash.new()
files.each {|f| index[f] = compute_something(f) }

or:

index = files.inject(Hash.new) {|i,f| i[f] = compute_something(f); i }

I was wondering if there's a more succinct and readable way?

TIA,

Nick
 
J

Joel VanderWerf

Nick said:
Hi,

Can anyone suggest an idiomatic ruby equivalent to this perl snippet?

my %index = map { $_ => compute_something($_) } @files;

Where @files is an array of filenames, and compute_something is a
subroutine which does some probably expensive operation on the file.

The result is a hash indexing the file name to the computed result for
that file. This and it's grep equivalent is something I find quite
quite handy in perl.

The best I came up with so far seems reletively clunky to me:

index = Hash.new()
files.each {|f| index[f] = compute_something(f) }

or:

index = files.inject(Hash.new) {|i,f| i[f] = compute_something(f); i }

I was wondering if there's a more succinct and readable way?

I'm not aware of anything more succinct to do what you wrote here, but
if you want to defer the expensive operation, you can do this:

index = Hash.new { |h,f| h[f] = compute_something(f) }

Maybe there should be something like this:

class Array
def hashmap
h={}
each {|x| h[x] = yield x}
h
end
end

[1,2,3].hashmap {|x| x*10}
# => {1=>10, 2=>20, 3=>30}
 
A

Ara.T.Howard

Hi,

Can anyone suggest an idiomatic ruby equivalent to this perl snippet?

my %index = map { $_ => compute_something($_) } @files;

Where @files is an array of filenames, and compute_something is a
subroutine which does some probably expensive operation on the file.

The result is a hash indexing the file name to the computed result for
that file. This and it's grep equivalent is something I find quite
quite handy in perl.

The best I came up with so far seems reletively clunky to me:

index = Hash.new()
files.each {|f| index[f] = compute_something(f) }

or:

index = files.inject(Hash.new) {|i,f| i[f] = compute_something(f); i }

I was wondering if there's a more succinct and readable way?

TIA,

Nick

index = Hash::new{|h,f| h[f] = compute_something f}

hashes can take a block to define how to initialize new values based on keys.

one benefit is that this means the 'compute_something' bit is lazy.

hth.

-a
--
===============================================================================
| email :: ara [dot] t [dot] howard [at] noaa [dot] gov
| phone :: 303.497.6469
| renunciation is not getting rid of the things of this world, but accepting
| that they pass away. --aitken roshi
===============================================================================
 
J

John Carter

Can anyone suggest an idiomatic ruby equivalent to this perl snippet?

my %index = map { $_ => compute_something($_) } @files;
The best I came up with so far seems reletively clunky to me:

index = Hash.new()
files.each {|f| index[f] = compute_something(f) }

If you want mind bending and obscure, try...

index = Hash.new{|hash,key| hash[key] = compute_something(key)}

and then somewhere totally elsewhen in the code...

files.each{|f| index[f]}


John Carter Phone : (64)(3) 358 6639
Tait Electronics Fax : (64)(3) 359 4632
PO Box 1645 Christchurch Email : (e-mail address removed)
New Zealand


Somewhere on the edge of a Galaxy, one of literally billions of such
galaxies, is a sun, one of literally billions of suns in that
galaxy.

Orbiting that sun is a small rock 330000 times smaller than that
sun.

This rock is covered by a very very thin scum of life. (Think 6000km
of rock followed by a meter or so of biomass.)

Amongst the millions of species in that scum are many hundreds of
thousands of types beetle and a mere handful of primates.

Surprisingly enough, this email does not originate from a beetle.

It originates from just one of the 6 billion vastly outnumbered humans.

I trust you will keep this perspective and context in mind when
reacting to this email.
 
L

Logan Capaldo

class Array
def hashmap
h={}
each {|x| h[x] = yield x}
h
end
end

[1,2,3].hashmap {|x| x*10}
# => {1=>10, 2=>20, 3=>30}

Wouldn't it make more sense to put #hashmap in module Enumerable?
Just a thought.
 
R

Robert Klemme

John Carter said:
Can anyone suggest an idiomatic ruby equivalent to this perl snippet?

my %index = map { $_ => compute_something($_) } @files;
The best I came up with so far seems reletively clunky to me:

index = Hash.new()
files.each {|f| index[f] = compute_something(f) }

If you want mind bending and obscure, try...

index = Hash.new{|hash,key| hash[key] = compute_something(key)}

and then somewhere totally elsewhen in the code...

files.each{|f| index[f]}

That's not really equivalent to what Nick requested and it's more clunky
also.

I prefer a solution with - guess what - #inject, but Hash[] does work, too:
=> [1, 2, 3]
a.inject({}) {|h,i| h=i+10; h}

=> {1=>11, 2=>12, 3=>13}
Hash[ *a.map{|i| [i,i+10]}.flatten ]
=> {1=>11, 2=>12, 3=>13}

Kind regards

robert
 
J

Joel VanderWerf

Logan said:
class Array
def hashmap
h={}
each {|x| h[x] = yield x}
h
end
end

[1,2,3].hashmap {|x| x*10}
# => {1=>10, 2=>20, 3=>30}


Wouldn't it make more sense to put #hashmap in module Enumerable?
Just a thought.

Of course. It would also probably make sense to choose a better name.
#map_to_hash, maybe?.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,173
Messages
2,570,938
Members
47,474
Latest member
VivianStuk

Latest Threads

Top