ruby picture

RCR 148: Enumerable#make_hash to simplify hash generation

Submitted by legacy (Mon Jul 21 06:07:56 UTC 2003)

Abstract

This is a legacy RCR from Ruby Garden, submitted by Gavin. Matz has declared these RCRs obsolete, and asked that their authors resubmit them in the new format.

A common idiom for hash generation is


    
  hash = {}
  obj.each do |x|
    hash[x] = some_method(x)
  end
  hash

    

I like hashes, but I don't like repeated scaffolding code. The above code could reduce to


    
  hash = obj.make_hash { |x| x, some_method(x) }

    

Here is an implementation of "make_hash":


    
  module Enumerable
    def make_hash
      result = {}
      each do |elt|
        key, value = yield(elt)
        result[key] = value
      end
      result
    end
  end

    

This allows easy, flexible, and (hopefully you'll agree) readable generation of hashes.

Problem

(RCR imported from old format)

Proposal

Analysis

(RCR imported from old format)

Implementation

(RCR imported from old format)
ruby picture
Comments Current voting

Correction (Gavin, 2003-07-21 10:56:24)

David Black pointed out that the client code would actually look like this:

            
  obj.make_hash { |x| [x, some_method(x)] }

            

The code as I originally presented it won't parse.

How about Enum#into(dest) instead ? (neoneye, 2003-07-21 17:22:54)

I have been discussing #into with Brian Candler, here:
>>ruby-talk:76605

Some examples (pseudo code):

[1, 2, 3].into({}){|i| [i, f(i)]}
  1. {1=>"f(1)", 2=>"f(3)", 3=>"f(3)"}

[1, 2, 3].into(""){|i| i.class}
  1. "FixnumFixnumFixnum"

[1, 2, 3].build(Array){|i| Regex.new(i.to_s)}
  1. [/1/, /2/, /3/]

            

I do prefer #into instead of #make_hash.
Just a thought ?

--
Simon Strandgaard

Quite similar to Enum#inject (, 2003-07-21 20:35:11)

This reminds me of Enumerable#inject even though your proposed version is a tiny bit simpler:

  <li>
    <code>[1, 2, 3].into({}){|i| [i, f(i)]}</code><br>
    => <code>[1, 2, 3].inject({}) { |state, elm| state[elm] 
  </li>  <li>
    <code>[1, 2, 3].into(""){|i| i.class}</code><br>
    => <code>[1, 2, 3].inject("") { |state, elm| state + elm.class.to_s }</code>
  </li>  <li>
    <code>[1, 2, 3].build(Array){|i| Regex.new(i.to_s)}</code><br>
    => <code>[1, 2, 3].inject([]) { |state, elm| state 
  </li>

[Correction] Quite similar to Enum#inject (, 2003-07-21 20:47:56)

This reminds me of Enumerable#inject even though your proposed version is a tiny bit simpler:

  <li>
    <code>[1, 2, 3].into({}){|i| [i, f(i)]}</code><br>
    => <code>[1, 2, 3].inject({}) { |state, elm| state[elm] &amp;lt;&amp;lt; f(elm); state }</code>
  </li>  <li>
    <code>[1, 2, 3].into(""){|i| i.class}</code><br>
    => <code>[1, 2, 3].inject("") { |state, elm| state + elm.class.to_s }</code>
  </li>  <li>
    <code>[1, 2, 3].build(Array){|i| Regex.new(i.to_s)}</code><br>
    => <code>[1, 2, 3].inject([]) { |state, elm| state &amp;lt;&amp;lt; Regexp.new(elm.to_s) }</code>
  </li>

What are the cons? (Gavin, 2003-07-24 01:15:11)

Some people have voted "rather not". No comment has been made so far on the drawbacks of this RCR. Anyone...?

Re: What are the cons? (neoneye, 2003-07-24 19:00:23)

I voted 'rather not', because of my standard scepticism :-)

Instead I suggested

h = Enum#into(Hash.new)
Which I think is nicer.. but thats just me.

--
Simon Strandgaard

Re: What are the cons? (Gavin, 2003-07-25 09:11:32)

It may be nicer in the sense that it's more general, but a specific task like building a hash warrants a specific method, IMO.

It's not nice that a powerful and common task like this should require the specification of the initial value.

In other words, if Enumerable#into were implemented, which I think is a good idea, we wouldn't deprecate #collect/#map, even though they would be logically redundant.

Summary:
 - #collect is an essential tool for working with arrays<br />
 - hashes are just as important as arrays for productive Ruby programming<br />
 - therefore, #collect-like functionality should be provided for hashes<br />

The #into suggestion is relevant, but hashes deserve special treatment for this kind of generation that strings, etc. do not.


Strongly opposed 0
Opposed 0
Neutral 0
In favor 0
Strongly advocate 0
ruby picture
If you have registered at RCRchive, you may now sign in below. If you have not registered, you may sign up for a username and password. Registering enables you to submit new RCRs, and vote and leave comments on existing RCRs.
Your username:
Your password:

ruby picture

Powered by .