From: Brian Candler Date: 2008-10-01T21:56:34+09:00 Subject: Re: Mode method for Array 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/.