Project

General

Profile

Feature #15143

Extend `Enumerable#to_h`

Added by sawa (Tsuyoshi Sawada) almost 2 years ago. Updated almost 2 years 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

Updated by sawa (Tsuyoshi Sawada) almost 2 years 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) almost 2 years ago

  • Assignee set to nobu (Nobuyoshi Nakada)

Sounds reasonable. Accepted.

Matz.

#3

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

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

Updated by nobu (Nobuyoshi Nakada) almost 2 years 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) almost 2 years 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) almost 2 years ago

nobu (Nobuyoshi Nakada) wrote:

Have you changed the mind since #10208?

Or since... #666!

Updated by sawa (Tsuyoshi Sawada) almost 2 years 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) almost 2 years 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) almost 2 years ago

I changed my mind when I approved to_h.

Matz.

Updated by matz (Yukihiro Matsumoto) almost 2 years 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) almost 2 years ago

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

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

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

Updated by nobu (Nobuyoshi Nakada) almost 2 years ago

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

#14

Updated by nobu (Nobuyoshi Nakada) almost 2 years 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) almost 2 years 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