Feature #15143
closedExtend `Enumerable#to_h`
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.
Updated by sawa (Tsuyoshi Sawada) about 6 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) about 6 years ago
- Assignee set to nobu (Nobuyoshi Nakada)
Sounds reasonable. Accepted.
Matz.
Updated by nobu (Nobuyoshi Nakada) about 6 years ago
- Is duplicate of Feature #10208: Passing block to Enumerable#to_h added
Updated by nobu (Nobuyoshi Nakada) about 6 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) about 6 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) about 6 years ago
Updated by sawa (Tsuyoshi Sawada) about 6 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) about 6 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) about 6 years ago
I changed my mind when I approved to_h
.
Matz.
Updated by matz (Yukihiro Matsumoto) about 6 years ago
I don't agree with @mame's idea. The return value from the block should be strictly 2 elements array.
Matz.
Updated by sawa (Tsuyoshi Sawada) about 6 years ago
Matz, thanks for confirmation. I am happy with my original proposal.
Updated by nobu (Nobuyoshi Nakada) about 6 years ago
OK, not only Enumerable
, but Array
, Hash
, ENV
, NilClass
and Struct
too?
Updated by nobu (Nobuyoshi Nakada) about 6 years ago
nil
isn't an Enumerable
, so it's irrelevant.
Updated by nobu (Nobuyoshi Nakada) about 6 years ago
- Status changed from Open to Closed
Updated by sawa (Tsuyoshi Sawada) about 6 years ago
nobu (Nobuyoshi Nakada) wrote:
OK, not only
Enumerable
, butArray
,Hash
,ENV
,NilClass
andStruct
too?
Thanks for reminding me about that and implementing it.