Project

General

Profile

Feature #15143

Extend `Enumerable#to_h`

Added by sawa (Tsuyoshi Sawada) about 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-core:89088]

Description

Often, we call Array#to_h to the result of Enumerable#map:

(1..5).map{|x| [x, x ** 2]}.to_h
#=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}

I am thinking of a feature to do this in a single method call.

Currently, Enumerable#to_h does not accept a block. I propose that, when Enumerable#to_h is called with a block (that has a subarray representing a key-value pair), return a hash that would be returned by applying the block to map, and to_h to the result:

(1..5).to_h{|x| [x, x ** 2]}
#=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}

Ideally, I request this to be done internally to Ruby without creating an intermediate parent array.


Related issues

Is duplicate of Ruby master - Feature #10208: Passing block to Enumerable#to_hClosedActions

Associated revisions

Revision abe75149
Added by nobu (Nobuyoshi Nakada) about 1 year ago

Enumerable#to_h with block and so on

[Feature #15143]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Revision 64794
Added by nobu (Nobuyoshi Nakada) about 1 year ago

Enumerable#to_h with block and so on

[Feature #15143]

Revision 64794
Added by nobu (Nobuyoshi Nakada) about 1 year ago

Enumerable#to_h with block and so on

[Feature #15143]

History

Updated by sawa (Tsuyoshi Sawada) about 1 year ago

I forgot to mention that people alternatively do:

(1..5).each_with_object({}){|x, h| h[x] = x ** 2}
#=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}

which may be more optimal than calling map. The proposed feature also has the effect of making this technique unnecessary (although the proposal is not as effective as this in that the former creates intermediate subarrays).

Updated by matz (Yukihiro Matsumoto) about 1 year ago

  • Assignee set to nobu (Nobuyoshi Nakada)

Sounds reasonable. Accepted.

Matz.

#3

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Is duplicate of Feature #10208: Passing block to Enumerable#to_h added

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Subject changed from Extend `Enumerrable#to_h` to Extend `Enumerable#to_h`

Have you changed the mind since #10208?

Updated by mame (Yusuke Endoh) about 1 year ago

If the block returns an array whose length is > 2, how does it behave?

%w(aa1 ab2 ba3 bb4).to_h {|s| s.chars }
 #=> { "a" => { "a" => "1",
                "b" => "2" },
       "b" => { "a" => "3",
                "b" => "4" } }

I expect very useful trie generator :-)

Updated by marcandre (Marc-Andre Lafortune) about 1 year ago

nobu (Nobuyoshi Nakada) wrote:

Have you changed the mind since #10208?

Or since... #666!

Updated by sawa (Tsuyoshi Sawada) about 1 year ago

Sorry that I missed the previous duplicate proposals (I found that I had even commented on one of them, which I had forgotten about). But it looks like four years have passed since then, and the situation has changed perhaps. Or, it may have worth proposing again to indicate that many people want such feature.

I am grateful to Matz for accepting this.

Updated by sawa (Tsuyoshi Sawada) about 1 year ago

mame (Yusuke Endoh) wrote:

If the block returns an array whose length is > 2, how does it behave?

%w(aa1 ab2 ba3 bb4).to_h {|s| s.chars }
 #=> { "a" => { "a" => "1",
                "b" => "2" },
       "b" => { "a" => "3",
                "b" => "4" } }

I expect very useful trie generator :-)

My original proposal is to follow the behaviour of the current map.{...}.to_h, which means to raise ArgumentError: wrong array length at 0 (expected 2, was 3).

However, mame's proposal to extend the feature also sounds interesting and good. Though, after having Matz' acceptance of this proposal, I am not sure whether we can still get another approval on top of it from him assuming mame's extension, or whether the extension should be another issue.

Updated by matz (Yukihiro Matsumoto) about 1 year ago

I changed my mind when I approved to_h.

Matz.

Updated by matz (Yukihiro Matsumoto) about 1 year ago

I don't agree with mame (Yusuke Endoh)'s idea. The return value from the block should be strictly 2 elements array.

Matz.

Updated by sawa (Tsuyoshi Sawada) about 1 year ago

Matz, thanks for confirmation. I am happy with my original proposal.

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

OK, not only Enumerable, but Array, Hash, ENV, NilClass and Struct too?

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

nil isn't an Enumerable, so it's irrelevant.

#14

Updated by nobu (Nobuyoshi Nakada) about 1 year ago

  • Status changed from Open to Closed

Applied in changeset trunk|r64794.


Enumerable#to_h with block and so on

[Feature #15143]

Updated by sawa (Tsuyoshi Sawada) about 1 year ago

nobu (Nobuyoshi Nakada) wrote:

OK, not only Enumerable, but Array, Hash, ENV, NilClass and Struct too?

Thanks for reminding me about that and implementing it.

Also available in: Atom PDF