From: Markus Fischer Date: 2011-06-09T23:03:20+09:00 Subject: [ruby-core:36889] [Ruby 1.9 - Feature #666] Enumerable::to_hash Issue #666 has been updated by Markus Fischer. Arnau Sanchez wrote: > I don't know if it's polite to comment in old closed issues, excuse me if it's not. > > I have to say that I wholeheartedly agree with Marc-Andre: the lack of Enumerable-to-Hash conversion is important; in my experience it's an extraordinarily common transformation. Let's see what people usually does (unaware of Facet's Enumerable#mash): [...] > Hash[(1..3).map { |n| [n, n**2] }] > > Not bad, but it's disappointing in a OOP language to "go back", you'd expect to write from left-to-right as usual and use a method. Moreover, it's less efficient because it needs an intermediate array to be built. > > Somehow it's already defined: > > >> Hash[[1,2,3]] > => {} > > Although it would be also ok to raise an exception (as Python does, for example). A mapping has been always represented by a collection of pairs (key, value), all languages with minimal functional capabilities (and Ruby has powerful ones) has such function/method transformation. I was about to open a new feature request when I found this, unfortunately rejected, issue. I'd also love to see Hash[] being available as Array#to_h too; it's just much more convenient. I recently had the urge to sort a hash and would could have been: some_hash.sort { |a,b| whatever_is_necessary }.to_h had to be Hash[ some_hash.sort { |a,b| whatever_is_necessary } ] - Markus ---------------------------------------- Feature #666: Enumerable::to_hash http://redmine.ruby-lang.org/issues/666 Author: Marc-Andre Lafortune Status: Rejected Priority: Low Assignee: Yukihiro Matsumoto Category: Target version: 1.9.x =begin There are many ways to obtain an array from enumerables (to_a, map, ...). There is no natural way to obtain a hash from an enumerable (except for Hash[some_array]). There is a Hash::to_a but no Array::to_hash. Here is what I would like: [[:hello, "world"], [:choice, [:red_pill, :blue_pill]]].to_hash ==> {:hello=>"world", :choice=>[:red_pill, :blue_pill]} (1..3).to_hash{|n| [n, n**2]} ==> {1 => 1, 2 ==> 4, 3 ==> 9} I propose to add the following Enumerable::to_hash : module Enumerable def to_hash result = {} self.each do |key, value| key, value = yield(key, value) if block_given? result[key] = value end result end end Since Hash::to_a returns an array of key-value pairs, I fell it's natural that a block to construct a Hash should return key-value pairs. This definition has nice symmetric properties: for any Hash h, the following all return a copy of h. h.to_a.to_hash h.to_hash{|p| p} h.to_hash{|k,v| [k,v]} h.keys.zip(h.values).to_hash Thank you for your attention, Marc-Andre Lafortune =end -- http://redmine.ruby-lang.org