David A. Black wrote:
What say you, oh inject king?
I don't know who that is, but I'll add my 2c anyway:
As much as I like inject, I have to say I've always felt that the ones
that look like this:
inject({}) {|h,item| do_something; h }
are kind of unidiomatic.
I agree; 'inject' is ideally for when you're creating a new data
structure each iteration rather than modifying an existing one. You
could do
inject({}) {|h,item| h.merge(something => otherthing)}
but that creates lots of waste.
I only used it as a convenient holder for the target object. Maybe
there's a more ruby-ish pattern where the target is the same each time
round, although I don't know what you'd call it:
module Enumerable
def into(obj)
each { |e| yield obj, e }
obj
end
end
src = {:foo=>1, :bar=>1, :baz=>2}
p src.into({}) { |tgt,(k,v)| (tgt[v] ||= ) << k }
There was also a previous suggestion of generalising map so that it
would build into an arbitary object, not just an array.
module Enumerable
def map2(target = )
each { |e| target << (yield e) }
target
end
end
p [1,2,3].map2 { |e| e * 2 }
class Hash
def <<(x)
self[x[0]] = x[1]
end
end
p [1,2,3].map2({}) { |e| [e, e * 2] }
That would allow any target which implements :<<, so map to $stdout
would be fine.
It's not so useful here, since we'd need a :<< method suitable for hash
inversion. And I suppose for completeness, you'd need a wrapper class
analagous to Enumerator to map :<< to an arbitary method name...
···
--
Posted via http://www.ruby-forum.com/\.