[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

mapping an array to a hash?

Nick Woolley

5/3/2005 10:13:00 PM

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



6 Answers

Joel VanderWerf

5/3/2005 10:23:00 PM

0

Nick Woolley wrote:
> 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}


Ara.T.Howard

5/3/2005 10:26:00 PM

0

John Carter

5/3/2005 10:29:00 PM

0

Logan Capaldo

5/4/2005 12:42:00 AM

0

On 5/3/05, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

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



Robert Klemme

5/4/2005 5:29:00 AM

0


"John Carter" <john.carter@tait.co.nz> schrieb im Newsbeitrag
news:Pine.LNX.4.61.0505041025210.25628@parore.tait.co.nz...
> On Wed, 4 May 2005, Nick Woolley wrote:
>
>> 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:

>> a = [1,2,3]
=> [1, 2, 3]

>> a.inject({}) {|h,i| h[i]=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

Joel VanderWerf

5/4/2005 9:01:00 PM

0

Logan Capaldo wrote:
> On 5/3/05, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:
>
>
>>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?.