Hi --
I'm still not sure what you have in mind for an implementation. Would it be something like this?
class Hash
def map_to_hash
h = Hash.new
keys.each do |key|
h[key] = yield(self[key])
end
h
end
def map_to_hash!
replace(map_to_hash)
end
end
which would then let you do this:
h = {1,2,3,4,5,6}
p h.map_to_hash {|v| v * 10}
output => {5=>60, 1=>20, 3=>40}
As for Enumerable#collect returning an Array... that's true across the board. It's not favoritism :-) An array is the lowest common denominator, so to speak, in which an enumerable can be represented, so it's the representation of choice for collect, select, etc. You couldn't have every enumerable class return an object of its own class; that might sound like it makes sense for Hash, but for enumerables in general it wouldn't. (Think of File#collect....)
-- David Black
[Edited the proposal to clear things up a bit] Yeah, that's pretty much what I mean. I might think that Enumerable#collect and the previously proposed "Mappable"'s #collect could be different, if that would be acceptable. Other than that, a different method name would be needed to represent the different paradigm. It would also be useful for things other than Hashes which are associative, but I'm not saying it should be used for things with pure-integral indeces (unless you want to sparsify something using a collect_to_hash identity transform, which would be better as Array#map_to_hash (not Array#to_hash, however, which should be the inverse of Hash#to_a.))
-- Zallus Kanite
I am very much in favour if this kind of functionality. So much so that I implemented it as Enumerable#build_hash in the 'extensions' project ( So I'd like to see it included in Ruby, but at least I can easily use it in the meantime.
-- Gavin Sinclair
I don't really have a better suggestion; but I don't really like the name "collect_to_hash". Unless we simply override Hash#collect / Hash#map which ofcourse break backwards compatibility.
Strongly advocate to the idea though. Was going to suggest it myself when I found it was already suggested here.
Might this be a better solution: Array#to_hash ? It takes an associative array, and converts it to a hash. It can be loosely defined thus:
class Array
def to_hash
Hash[ *(self.flatten) ]
end
end
The real solution would be to return associative pairs from a #map/#collect, and then turn them into a hash with an additional step. It's cleaner, and avoids the need to add this functionality to all Enumerable members.
Perhaps, though, one might want #to_hash to accept a block, being a transformation to apply to the elements of an Enumerable to get key-value pairs.
module Enumerable
def to_hash
hsh = {}
each{ |elem|
elem = yield( elem ) if block_given?
hsh[ elem[ 0 ] ] = elem[ 1 ]
}
hsh
end
end
end
I'm sure this would be greatly sped up by being re-written in C. Given it's wide-ranging use, I strongly believe this belongs in the standard Ruby library.
Hi --
I'm still not sure what you have in mind for an implementation. Would it be something like this?
which would then let you do this:
As for Enumerable#collect returning an Array... that's true across the board. It's not favoritism :-) An array is the lowest common denominator, so to speak, in which an enumerable can be represented, so it's the representation of choice for collect, select, etc. You couldn't have every enumerable class return an object of its own class; that might sound like it makes sense for Hash, but for enumerables in general it wouldn't. (Think of File#collect....)
-- David Black
[Edited the proposal to clear things up a bit] Yeah, that's pretty much what I mean. I might think that Enumerable#collect and the previously proposed "Mappable"'s #collect could be different, if that would be acceptable. Other than that, a different method name would be needed to represent the different paradigm. It would also be useful for things other than Hashes which are associative, but I'm not saying it should be used for things with pure-integral indeces (unless you want to sparsify something using a collect_to_hash identity transform, which would be better as Array#map_to_hash (not Array#to_hash, however, which should be the inverse of Hash#to_a.))
-- Zallus Kanite
I am very much in favour if this kind of functionality. So much so that I implemented it as Enumerable#build_hash in the 'extensions' project ( So I'd like to see it included in Ruby, but at least I can easily use it in the meantime.
-- Gavin Sinclair
I don't really have a better suggestion; but I don't really like the name "collect_to_hash". Unless we simply override Hash#collect / Hash#map which ofcourse break backwards compatibility.
Strongly advocate to the idea though. Was going to suggest it myself when I found it was already suggested here.
Might this be a better solution: Array#to_hash ? It takes an associative array, and converts it to a hash. It can be loosely defined thus:
The real solution would be to return associative pairs from a #map/#collect, and then turn them into a hash with an additional step. It's cleaner, and avoids the need to add this functionality to all Enumerable members.
Perhaps, though, one might want #to_hash to accept a block, being a transformation to apply to the elements of an Enumerable to get key-value pairs.
I'm sure this would be greatly sped up by being re-written in C. Given it's wide-ranging use, I strongly believe this belongs in the standard Ruby library.