I'd like to use that bit for a small discussion if you allow. I
believe the implementation would be better off by not messing with
return values from the block because the changes lead to more complex
code and results may be surprising (i.e. if you relied on returning
nil or false and expected that to show up in the new Hash). By having
the method do less things it becomes more flexible to use.
Another interesting question is which is the proper method for
creating the new Hash? I can think at least of these as reasonable
solutions
h = {}
h = Hash.new(default)
h = Hash.new(&default_proc)
h = default_proc ? Hash.new(&default_proc) : Hash.new(default)
h = self.class.new
h = self.class.new(default)
h = self.class.new(&default_proc)
h = dup.clear
The solution might be to do
def map2(h = {})
each do |k,v|
k, v = yield k, v
h[k] = v
end
h
end
i.e. allow the caller to decide where he wants the mapped data to go
while defaulting to the most straightforward case, a new Hash. This is
similar to what Enumerable#map does, i.e. it creates a new Array
regardless of the type at hand.
Kind regards
robert
···
2008/8/21 Peña, Botp <botp@delmonte-phil.com>:
From: Brian Ross [mailto:p.brian.ross@gmail.com]
# I'd imagine that this would return map as a new hash with the
# keys modified. Is there anything like collect! for hashes?
the required pairings for hashes makes it fragile to implement a map/collect like feature similar to plain arrays.
you can create one if you like. just be careful.
eg, here is my simple-minded implementation,
irb(main):084:0> class Hash
irb(main):085:1> def map2
irb(main):086:2> h={}
irb(main):087:2> self.each do |k,v|
irb(main):088:3* kk,vv=yield(k,v)
irb(main):089:3> key = kk || k
irb(main):090:3> val = vv || v
irb(main):091:3> h[key] = val
irb(main):092:3> end
irb(main):093:2> h
irb(main):094:2> end
irb(main):095:1> end
=> nil
--
use.inject do |as, often| as.you_can - without end
Note though that this unfortunately creates a lot of temporary Hashes
that are thrown away immediately. I personally find that more ugly
than the h at the end. You can reformat to make it less stand out as
in
map = hash.inject {} do |h,(k,v)|
h[k.upcase] = v; h
end
Kind regards
robert
···
2008/8/20 Martin DeMello <martindemello@gmail.com>:
On Wed, Aug 20, 2008 at 11:26 AM, Robert Klemme > <shortcutter@googlemail.com> wrote:
Folks, thanks for leaving the #inject solution to me.
map = hash.inject({}) do |h,(k,v)|
h[k.upcase] = v
h
end