From: Guido De Rosa Date: 2010-10-08T02:18:48+09:00 Subject: Re: "map" a deeply nested structure: Object#deep_map Thomas Sawyer wrote: > Perhaps what is being sought here is a form of search and replace. > > class Array > def deep_replace(replacement, &match) > map do |e| > if e.respond_to?(:deep_replace) > e.deep_replace(replacement, &match) > else > match[e] ? replacement : e > end > end > end > > require 'facets/hash/mash' #[1] > > class Hash > def deep_replace(replacement, &match) > mash do |k,v| > nk = if k.respond_to?(:deep_replace) > k.deep_replace(replacement, &match) > else > match[k] ? replacement : k > end > nv = if v.respond_to?(:deep_replace) > v.deep_replace(replacement, &match) > else > match[v] ? replacement : v > end > [nk, nv] > end > end > > Not tested but you get the idea. > > I'm not 100% sure about handling the key for Hash either, but perhaps > an option could toggle that usage on or off. > > [1]http://blog.thepete.net/2010/02/ruby-facets-mash-method.html That way you can say for example: Here's a deeply nested object; replace any "content" n which is a Fixnum with the number 123 But you cannot say: Here's a deeply nested object; replace any "content" n which is a Fixnum with the number n + 1 #deep_replace would be a lot more flexible if replacement could be a lambda. The drawback is that client code would look ugly: o.deep_replace(lambda {|x| x+1}) {|y| ...} Is there an elegant way o pass *two* blocks of code? Maybe a more consistent API would look like: o.deep_replace( lambda {|x| ... }, # matching conditions lambda {|x| ... } # replacement code ) or like: o.deep_replace( lambda {|k, v| ... }, # matching conditions lambda {|k, v| ... [new_k, new_v] } # replacement code ) But more simply the "matching" may be done by the client code: o.deep_replace do |k, v| if matching_conditions(k, v) # do the replecement ... [new_k, new_v] else [k, v] # leave the same end end so, again, we have to pass one block of code, but for the replacement, not the match. G. -- Posted via http://www.ruby-forum.com/.