Forum: Ruby-core [ruby-trunk - Feature #6669][Open] A method like Hash#map but returns hash

Posted by yhara (Yutaka HARA) (Guest)
on 2012-06-29 19:23
(Received via mailing list)
Issue #6669 has been reported by yhara (Yutaka HARA).

----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669

Author: yhara (Yutaka HARA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by yhara (Yutaka HARA) (Guest)
on 2012-06-29 19:27
(Received via mailing list)
Issue #6669 has been updated by yhara (Yutaka HARA).

File 6669.pdf added

Adding presentation slide for the feature request meeting 
([ruby-dev:45708])
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-27566

Author: yhara (Yutaka HARA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by Thomas Sawyer (7rans)
on 2012-06-29 19:35
(Received via mailing list)
Issue #6669 has been updated by trans (Thomas Sawyer).


Hi, I just want to mention that Facets has this using name #mash (map 
hash) with alias #graph, which was the original name. So those are two 
names to consider. Thanks.
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-27567

Author: yhara (Yutaka HARA)
Status: Open
Priority: Normal
Assignee:
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by mame (Yusuke Endoh) (Guest)
on 2012-07-01 18:37
(Received via mailing list)
Issue #6669 has been updated by mame (Yusuke Endoh).

Status changed from Open to Assigned
Assignee set to matz (Yukihiro Matsumoto)

Received, thank you!

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-27668

Author: yhara (Yutaka HARA)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by matz (Yukihiro Matsumoto) (Guest)
on 2012-07-21 11:13
(Received via mailing list)
Issue #6669 has been updated by matz (Yukihiro Matsumoto).


Since Hash#reject, Hash#select does return a hash, I think it's OK for 
Hash#collect to return a hash.

I believe Hash#map should return an array as before, just like find_all 
does.

Matz.

----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-28249

Author: yhara (Yutaka HARA)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by "Martin J. Dürst" <duerst@it.aoyama.ac.jp> (Guest)
on 2012-07-21 12:37
(Received via mailing list)
On 2012/07/21 18:12, matz (Yukihiro Matsumoto) wrote:
>
> Issue #6669 has been updated by matz (Yukihiro Matsumoto).
>
>
> Since Hash#reject, Hash#select does return a hash, I think it's OK for 
Hash#collect to return a hash.
>
> I believe Hash#map should return an array as before, just like find_all does.
>
> Matz.

Wouldn't it be really confusing that for Arrays, #map and #collect are
synonyms, but for Hash, they are different?

Regards,   Martin.
Posted by marcandre (Marc-Andre Lafortune) (Guest)
on 2012-07-21 23:52
(Received via mailing list)
Issue #6669 has been updated by marcandre (Marc-Andre Lafortune).


Hi,

duerst (Martin Dürst) wrote:
>  Wouldn't it be really confusing that for Arrays, #map and #collect are
>  synonyms, but for Hash, they are different?

It could be confusing, and would also introduce incompatibilities. Also, 
if the proposal for associate/categorize is accepted, then this 
`collect` would be a duplication.

I believe that methods like associate/categorize acting on all 
Enumerable to produce Hashes would be far more useful (since they don't 
only act on hashes), without introducing incompatibilities.
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-28264

Author: yhara (Yutaka HARA)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by Thomas Sawyer (7rans)
on 2012-07-22 16:06
(Received via mailing list)
Issue #6669 has been updated by trans (Thomas Sawyer).


It would introduce an incompatibility, but probably not as much as you 
might think since #map has become the more commonly used method and it 
is used even less frequently on a Hash.

I think it makes good sense to have a known set of methods that are 
*closed*, which is to say they return the same class of object. As matz 
points out, #select and #reject are already closed. #collect could be 
made closed without too much trouble since we still have the more widely 
used #map.

That doesn't get rid of the need for a better Array to Hash conversion 
method though, which has been discussed in other threads.


----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-28275

Author: yhara (Yutaka HARA)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by mame (Yusuke Endoh) (Guest)
on 2012-07-24 15:48
(Received via mailing list)
Issue #6669 has been updated by mame (Yusuke Endoh).

Status changed from Assigned to Feedback

Yutaka Hara,

We discussed your slide at the developer meeting (7/21).

Matz was positive to the feature itself, but there was no
method name that matz liked.  Please find another good name.


Here is a discussion summary:

* hash_map, map_hash
Matz's most favorite, but not enough to accept.

* associate
Not bad, but not enough to accept.

* mash
Such a created word is not good.

* apply, convert, process, graph
Bad.  They suggest something different.

* morph (Yugui suggested)
This might be a correct terminology (?), but it is difficult
for those unfamiliar with category theory.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-28394

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by merborne (kyo endo) (Guest)
on 2012-07-25 16:03
(Received via mailing list)
Issue #6669 has been updated by merborne (kyo endo).


how about #hmap.
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-28438

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by ryenus (_ ryenus) (Guest)
on 2012-09-19 07:31
(Received via mailing list)
Issue #6669 has been updated by ryenus (_ ryenus).


What about #remap

----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-29504

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by david_macmahon (David MacMahon) (Guest)
on 2012-09-19 08:10
(Received via mailing list)
Issue #6669 has been updated by david_macmahon (David MacMahon).


What about #map! (or are bang methods frowned upon these days)?
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-29505

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by david_macmahon (David MacMahon) (Guest)
on 2012-09-19 09:16
(Received via mailing list)
Issue #6669 has been updated by david_macmahon (David MacMahon).


Please ignore my previous comment; I see that you want a new Hash rather 
than replacing the keys/values of the existing Hash.  I guess you want a 
more efficient alternative to:

max_score = Hash[score.map {|k,v| [k, v.max]}]

Since you want to create a new Hash from an existing object, how about a 
Hash::map factory method:

class Hash
  def self.map(other, &block)
    other.inject({}) do |h, (k, v)|
      new_k, new_v = *block.call(k, v)
      h[new_k] = new_v
      h
    end
  end
end

Note that "other" doesn't even need to be a Hash (e.g. it could be an 
Array of two element Arrays).  In fact, this:

Hash.map([ [key, value], ... ]) {|*kv| kv}

would be equivalent to:

Hash[ [ [key, value], ... ] ]

Perhaps if Hash::map is not given a block, the behavior could be as if 
the "{|*kv| kv}" block had been given.
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-29509

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by Thomas Sawyer (7rans)
on 2012-09-19 16:43
(Received via mailing list)
Issue #6669 has been updated by trans (Thomas Sawyer).


> * mash
> Such a created word is not good.

I think when no other choices suffice one is left with two options, 
either created word or long explanatory term, e.g. #mash or #map_hash, 
respectively.

OTOH, recently I have been looking at new API related to this that uses 
fluent notation via an Enumerator-like "hashifier", e.g.

   enum.hashify.map

This approach allows for other methods to be defined to "hashify" in 
variant ways.

----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-29535

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: 2.0.0


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by yhara (Yutaka HARA) (Guest)
on 2012-10-25 09:36
(Received via mailing list)
Issue #6669 has been updated by yhara (Yutaka HARA).

Target version changed from 2.0.0 to next


----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-31501

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by Matthew Kerwin (mattyk)
on 2013-02-06 23:53
(Received via mailing list)
Issue #6669 has been updated by phluid61 (Matthew Kerwin).


I might also suggest the name `map_pairs`, derived from `each_pair`.  I 
think it's not incorrect, as the return value from `each_pair` is the 
original Hash object, so the return value from `map_pairs` could also be 
a Hash object.

Incidentally this paves the way for future possibilities, such as 
`map_keys` or `map_values` (as per `each_pair` and `each_value`)
----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-35949

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Posted by Matthew Kerwin (mattyk)
on 2013-03-13 03:25
(Received via mailing list)
Issue #6669 has been updated by phluid61 (Matthew Kerwin).


phluid61 (Matthew Kerwin) wrote:
> I might also suggest the name `map_pairs`, derived from `each_pair`.  I
> think it's not incorrect, as the return value from `each_pair` is the
> original Hash object, so the return value from `map_pairs` could also be
> a Hash object.
>
> Incidentally this paves the way for future possibilities, such as
> `map_keys` or `map_values` (as per `each_key` and `each_value`)

This is related to #7793.  I just released a gem that implements 
Hash#map_pairs, #map_keys, and #map_values. 
https://rubygems.org/gems/hashmap

----------------------------------------
Feature #6669: A method like Hash#map but returns hash
https://bugs.ruby-lang.org/issues/6669#change-37556

Author: yhara (Yutaka HARA)
Status: Feedback
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category: core
Target version: next minor


=begin
Given a hash h, h.map returns an array(alist), but sometimes I hope it 
returned a hash.

Example:

  class Hash
    def apply(&block)
      self.inject({}) do |h, (k, v)|
        new_k, new_v = *block.call(k, v)
        h[new_k] = new_v
        h
      end
    end
  end

  score = {
    taro: [1,3,2],
    jiro: [3,5,8,4],
    saburo: [2,9]
  }
  max_score = score.apply{|k,v| [k, v.max]}
  #=> {taro: 3, jiro: 8, saburo: 9}
  p max_score[:taro]
  #=> 3

I'm not thinking "apply" is a perfect name for this. Maybe "hash_map" is 
better
(we already have "flat_map").
=end
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.