<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: recursive code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sun, 18 May 2008 00:33:53 GMT</pubDate>
    <description>DZone Snippets: recursive code</description>
    <item>
      <title>Hash#deep_delete</title>
      <link>http://snippets.dzone.com/posts/show/4725</link>
      <description>&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class Object&lt;br /&gt;   def deep_clone&lt;br /&gt;      Marshal.load(Marshal.dump(self))&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Hash&lt;br /&gt;&lt;br /&gt;   # From: http://www.sameshirteveryday.com/2007/09/23/ruby-get-full-history-all-parents-of-a-hash-node&lt;br /&gt;   # Author: Alex Gorbatchev&lt;br /&gt;   # for further recursive hash methods see: &lt;br /&gt;   # - http://snippets.dzone.com/posts/show/1908&lt;br /&gt;   # - http://snippets.dzone.com/posts/show/4706&lt;br /&gt;   &lt;br /&gt;   def nested_key(desired_key, &amp;block)&lt;br /&gt;&lt;br /&gt;      return false unless Hash === self&lt;br /&gt;      #return false unless self.is_a?(Hash)&lt;br /&gt;&lt;br /&gt;      self.each_pair do |k,v|  &lt;br /&gt;         if k == desired_key or v.nested_key(desired_key, &amp;block)  &lt;br /&gt;            yield(k,v)  &lt;br /&gt;            return true  &lt;br /&gt;         end  &lt;br /&gt;      end  &lt;br /&gt;&lt;br /&gt;      return false  &lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def deep_values(key)   # cf. http://snippets.dzone.com/posts/show/1908 &lt;br /&gt;&lt;br /&gt;      hash = self.deep_clone&lt;br /&gt;      ret = []&lt;br /&gt;&lt;br /&gt;      begin&lt;br /&gt;&lt;br /&gt;         ar = []&lt;br /&gt;         result = hash.nested_key(key) { |k, v| ar &lt;&lt; k }&lt;br /&gt;         break unless result&lt;br /&gt;         ar = ar.reverse&lt;br /&gt;&lt;br /&gt;         hk = ""&lt;br /&gt;         ar.size.times { |i| hk &lt;&lt; "[ar[#{i}]]" }&lt;br /&gt;         #str = "hash" &lt;&lt; hk &lt;&lt; " rescue nil"&lt;br /&gt;         str = "hash" &lt;&lt; hk &lt;br /&gt;&lt;br /&gt;         # get value for hash key hk&lt;br /&gt;         ret &lt;&lt; eval(str)&lt;br /&gt;&lt;br /&gt;         # delete the hash key&lt;br /&gt;         key_to_delete = [ar.pop]&lt;br /&gt;&lt;br /&gt;         hk = ""&lt;br /&gt;         ar.size.times { |i| hk &lt;&lt; "[ar[#{i}]]" }&lt;br /&gt;         str = "hash" &lt;&lt; hk&lt;br /&gt;         str = str &lt;&lt; ".delete(key_to_delete.first)"&lt;br /&gt;         eval(str)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;      end while result&lt;br /&gt;&lt;br /&gt;      hash.clear  # optional&lt;br /&gt;      ret&lt;br /&gt;&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def deep_delete(key)&lt;br /&gt;&lt;br /&gt;      hash = self&lt;br /&gt;&lt;br /&gt;      begin&lt;br /&gt;&lt;br /&gt;         ar = []&lt;br /&gt;         result = hash.nested_key(key) { |k, v| ar &lt;&lt; k }&lt;br /&gt;         break unless result&lt;br /&gt;         ar = ar.reverse&lt;br /&gt;&lt;br /&gt;         # delete the hash key&lt;br /&gt;         key_to_delete = [ar.pop]&lt;br /&gt;&lt;br /&gt;         hk = ""&lt;br /&gt;         ar.size.times { |i| hk &lt;&lt; "[ar[#{i}]]" }&lt;br /&gt;         str = "hash" &lt;&lt; hk&lt;br /&gt;         str = str &lt;&lt; ".delete(key_to_delete.first)"&lt;br /&gt;         eval(str)&lt;br /&gt;&lt;br /&gt;      end while result&lt;br /&gt;&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;puts&lt;br /&gt;hash = {  &lt;br /&gt;  :level_1 =&gt; {  &lt;br /&gt;    :level_2 =&gt; {  :search =&gt; 'test1',&lt;br /&gt;      :level_3 =&gt; {  &lt;br /&gt;        :search =&gt; 'test2', :level_4 =&gt; {:search =&gt; 'test3'}&lt;br /&gt;      }  &lt;br /&gt;    }  &lt;br /&gt;  }  &lt;br /&gt;}  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;require 'pp'&lt;br /&gt;&lt;br /&gt;p hash&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;pp hash&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;hash.nested_key(:search) { |k, v| puts "#{k}  ::  #{v.inspect}" }&lt;br /&gt;&lt;br /&gt;# prints out...&lt;br /&gt;# search  ::  "test1"&lt;br /&gt;# level_2  ::  {:search=&gt;"test1", :level_3=&gt;{:search=&gt;"test2", :level_4=&gt;{:search=&gt;"test3"}}}&lt;br /&gt;# level_1  ::  {:level_2=&gt;{:search=&gt;"test1", :level_3=&gt;{:search=&gt;"test2", :level_4=&gt;{:search=&gt;"test3"}}}}&lt;br /&gt;&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;puts "DEEP VALUES"&lt;br /&gt;p hash.deep_values(:search)   #=&gt; ["test1", "test2", "test3"]&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;puts "DEEP VALUES DELETED"&lt;br /&gt;hash.deep_delete(:search)&lt;br /&gt;p hash   #=&gt; {:level_1=&gt;{:level_2=&gt;{:level_3=&gt;{:level_4=&gt;{}}}}}&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;puts "DEEP VALUES"&lt;br /&gt;p hash.deep_values(:search)   #=&gt; []&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 01 Nov 2007 15:42:50 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4725</guid>
      <author>ntk ()</author>
    </item>
    <item>
      <title>Hash#deep_merge</title>
      <link>http://snippets.dzone.com/posts/show/4706</link>
      <description>&lt;code&gt;&lt;br /&gt;&lt;br /&gt;# Hash#deep_merge&lt;br /&gt;# From: http://pastie.textmate.org/pastes/30372, Elliott Hird&lt;br /&gt;# Source: http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html&lt;br /&gt;# This file contains extensions to Ruby and other useful snippits of code.&lt;br /&gt;# Time to extend Hash with some recursive merging magic.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Hash&lt;br /&gt;&lt;br /&gt;  # Merges self with another hash, recursively.&lt;br /&gt;  # &lt;br /&gt;  # This code was lovingly stolen from some random gem:&lt;br /&gt;  # http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html&lt;br /&gt;  # &lt;br /&gt;  # Thanks to whoever made it.&lt;br /&gt;&lt;br /&gt;  def deep_merge(hash)&lt;br /&gt;    target = dup&lt;br /&gt;    &lt;br /&gt;    hash.keys.each do |key|&lt;br /&gt;      if hash[key].is_a? Hash and self[key].is_a? Hash&lt;br /&gt;        target[key] = target[key].deep_merge(hash[key])&lt;br /&gt;        next&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      target[key] = hash[key]&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    target&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  # From: http://www.gemtacular.com/gemdocs/cerberus-0.2.2/doc/classes/Hash.html&lt;br /&gt;  # File lib/cerberus/utils.rb, line 42&lt;br /&gt;&lt;br /&gt;  def deep_merge!(second)&lt;br /&gt;    second.each_pair do |k,v|&lt;br /&gt;      if self[k].is_a?(Hash) and second[k].is_a?(Hash)&lt;br /&gt;        self[k].deep_merge!(second[k])&lt;br /&gt;      else&lt;br /&gt;        self[k] = second[k]&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#-----------------&lt;br /&gt;        &lt;br /&gt;   # cf. http://subtech.g.hatena.ne.jp/cho45/20061122&lt;br /&gt;   def deep_merge2(other)&lt;br /&gt;      deep_proc = Proc.new { |k, s, o|&lt;br /&gt;         if s.kind_of?(Hash) &amp;&amp; o.kind_of?(Hash)&lt;br /&gt;            next s.merge(o, &amp;deep_proc)&lt;br /&gt;         end&lt;br /&gt;         next o&lt;br /&gt;      }&lt;br /&gt;      merge(other, &amp;deep_proc)&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def deep_merge3(second)&lt;br /&gt;&lt;br /&gt;      # From: http://www.ruby-forum.com/topic/142809&lt;br /&gt;      # Author: Stefan Rusterholz&lt;br /&gt;&lt;br /&gt;      merger = proc { |key,v1,v2| Hash === v1 &amp;&amp; Hash === v2 ? v1.merge(v2, &amp;merger) : v2 }&lt;br /&gt;      self.merge(second, &amp;merger)&lt;br /&gt;&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def keep_merge(hash)&lt;br /&gt;      target = dup&lt;br /&gt;      hash.keys.each do |key|&lt;br /&gt;         if hash[key].is_a? Hash and self[key].is_a? Hash&lt;br /&gt;            target[key] = target[key].keep_merge(hash[key])&lt;br /&gt;            next&lt;br /&gt;         end&lt;br /&gt;         #target[key] = hash[key]&lt;br /&gt;         target.update(hash) { |key, *values| values.flatten.uniq }&lt;br /&gt;      end&lt;br /&gt;      target&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h = {:a =&gt; {:b =&gt; :c}}.merge({:a =&gt; {:l =&gt; :x}})&lt;br /&gt;p h  #=&gt; {:a=&gt;{:l=&gt;:x}}&lt;br /&gt;&lt;br /&gt;h = {:a =&gt; {:b =&gt; :c}}.deep_merge({:a =&gt; {:l =&gt; :x}})&lt;br /&gt;p h  #=&gt; {:a=&gt;{:b=&gt;:c, :l=&gt;:x}}&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h1 = {:a =&gt; {:b =&gt; :c}}&lt;br /&gt;h2 = {:a =&gt; {:l =&gt; :x}}&lt;br /&gt;&lt;br /&gt;h = h1.deep_merge(h2)&lt;br /&gt;p h1, h2, h&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;h = h1.deep_merge2(h2)&lt;br /&gt;p h1, h2, h&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;h = h1.deep_merge!(h2)&lt;br /&gt;p h1, h2, h&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h1 = {:a =&gt; {:b =&gt; :c}}&lt;br /&gt;h2 = {:a =&gt; {:l =&gt; :x}}&lt;br /&gt;&lt;br /&gt;p h1.deep_merge3(h2)&lt;br /&gt;p h1, h2&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;first = {&lt;br /&gt;  :data=&gt;{&lt;br /&gt;    :name=&gt;{&lt;br /&gt;      :first=&gt;'Sam',&lt;br /&gt;      :middle=&gt;'I',&lt;br /&gt;      :last=&gt;'am'&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;second={&lt;br /&gt;  :data=&gt;{&lt;br /&gt;    :name=&gt;{&lt;br /&gt;      :middle=&gt;'you',&lt;br /&gt;      :last=&gt;'are'&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;p first.deep_merge3(second)&lt;br /&gt;#=&gt; {:data=&gt;{:name=&gt;{:middle=&gt;"you", :first=&gt;"Sam", :last=&gt;"are"}}}&lt;br /&gt;&lt;br /&gt;p first.keep_merge(second)&lt;br /&gt;#=&gt;  {:data=&gt;{:name=&gt;{:first=&gt;"Sam", :middle=&gt;["I", "you"], :last=&gt;["am", "are"]}}}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 27 Oct 2007 18:07:40 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4706</guid>
      <author>ntk ()</author>
    </item>
    <item>
      <title>Tower of Hanoi</title>
      <link>http://snippets.dzone.com/posts/show/4584</link>
      <description>Solves the old "Tower of Hanoi" problem using a recursive divide et impera approach.&lt;br /&gt;&lt;br /&gt;http://en.wikipedia.org/wiki/Tower_of_Hanoi&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;&lt;br /&gt;void hanoi(int n, char a, char b, char c) {&lt;br /&gt;	if (!n)	&lt;br /&gt;		return;&lt;br /&gt;	&lt;br /&gt;	hanoi(n - 1, a, c, b);&lt;br /&gt;	printf("%c -&gt; %c\n", a, b);&lt;br /&gt;	hanoi(n - 1, c, b, a);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main(int argc, char *argv[]) {&lt;br /&gt;	int n = 3;&lt;br /&gt;	hanoi(n, 'a', 'b', 'c');&lt;br /&gt;	&lt;br /&gt;	return 0;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 28 Sep 2007 06:37:43 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4584</guid>
      <author>scvalex (Alexandru Scvortov)</author>
    </item>
    <item>
      <title>Recursively dump imbricated Map of Maps</title>
      <link>http://snippets.dzone.com/posts/show/4531</link>
      <description>// description of your code here&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;    public void dumpMapOfMap(Map map) {&lt;br /&gt;        Set s = map.entrySet();&lt;br /&gt;        Iterator sit = s.iterator();&lt;br /&gt;        boolean isFirst = true;&lt;br /&gt;&lt;br /&gt;        while (sit.hasNext()) {&lt;br /&gt;            Map.Entry elem = (Map.Entry)sit.next();&lt;br /&gt;            String key = (String)elem.getKey();&lt;br /&gt;            Object value = elem.getValue();&lt;br /&gt;&lt;br /&gt;            if (value instanceof String) {&lt;br /&gt;                // recursivity stop condition&lt;br /&gt;                System.out.print(key);&lt;br /&gt;                System.out.print(" : ");&lt;br /&gt;                System.out.println(value);&lt;br /&gt;            } else {&lt;br /&gt;                if (!isFirst) {&lt;br /&gt;                    System.out.println("");&lt;br /&gt;                } else {&lt;br /&gt;                    isFirst = false;&lt;br /&gt;                }&lt;br /&gt;                System.out.println(key);&lt;br /&gt;                Map valueMap = (Map)elem.getValue();&lt;br /&gt;                dumpMapOfMap(valueMap);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 12 Sep 2007 12:58:09 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4531</guid>
      <author>Archanciel (Jean-Pierre Schnyder)</author>
    </item>
    <item>
      <title>Recursively find files by filename pattern.</title>
      <link>http://snippets.dzone.com/posts/show/4147</link>
      <description>Scans a directory, and all subdirectories for files, matching a regular expression. Each match is sent to the callback provided as third argument. A simple example:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function my_handler($filename) {&lt;br /&gt;  echo $filename . "\n";&lt;br /&gt;}&lt;br /&gt;find_files('c:/', '/php$/', 'my_handler');&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And the actual snippet&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function find_files($path, $pattern, $callback) {&lt;br /&gt;  $path = rtrim(str_replace("\\", "/", $path), '/') . '/';&lt;br /&gt;  $matches = Array();&lt;br /&gt;  $entries = Array();&lt;br /&gt;  $dir = dir($path);&lt;br /&gt;  while (false !== ($entry = $dir-&gt;read())) {&lt;br /&gt;    $entries[] = $entry;&lt;br /&gt;  }&lt;br /&gt;  $dir-&gt;close();&lt;br /&gt;  foreach ($entries as $entry) {&lt;br /&gt;    $fullname = $path . $entry;&lt;br /&gt;    if ($entry != '.' &amp;&amp; $entry != '..' &amp;&amp; is_dir($fullname)) {&lt;br /&gt;      find_files($fullname, $pattern, $callback);&lt;br /&gt;    } else if (is_file($fullname) &amp;&amp; preg_match($pattern, $entry)) {&lt;br /&gt;      call_user_func($callback, $fullname);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 15 Jun 2007 13:17:56 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4147</guid>
      <author>troelskn (Troels)</author>
    </item>
    <item>
      <title>Find every path and it's value in a Hash</title>
      <link>http://snippets.dzone.com/posts/show/3565</link>
      <description>Extends Hash class with each_path method.&lt;br /&gt;&lt;br /&gt;This method takes a block as argument which is called each time a the recursivly searched Hash returns a key that does not point to another Hash.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;paths = []&lt;br /&gt;complex_hash = Hash[&lt;br /&gt;  :a =&gt; { :aa =&gt; '1', :ab =&gt; '2' },&lt;br /&gt;  :b =&gt; { :ba =&gt; '3', :bb =&gt; '4' }&lt;br /&gt;]&lt;br /&gt;complex_hash.each_path { |path, value| paths &lt;&lt; [ path, value ] }&lt;br /&gt;paths.inspect&lt;br /&gt;# =&gt; "[[\"b/ba/\", \"3\"], [\"b/bb/\", \"4\"], [\"a/aa/\", \"1\"], [\"a/ab/\", \"2\"]]"&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;class Hash&lt;br /&gt;  def each_path&lt;br /&gt;    raise ArgumentError unless block_given?&lt;br /&gt;    self.class.each_path( self ) { |path, object| yield path, object }&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  protected&lt;br /&gt;  def self.each_path( object, path = '', &amp;block )&lt;br /&gt;    if object.is_a?( Hash ) then object.each do |key, value|&lt;br /&gt;        self.each_path value, "#{ path }#{ key }/", &amp;block&lt;br /&gt;      end&lt;br /&gt;    else yield path, object&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 22 Feb 2007 14:54:41 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3565</guid>
      <author>boof (Florian A&#223;mann)</author>
    </item>
    <item>
      <title>Extracting all keys from a multi-dimensional hash</title>
      <link>http://snippets.dzone.com/posts/show/1908</link>
      <description>Extract all complete key sequences from a multi-dimensional hash (with the last key not pointing to another hash; cf. h[1][2][3] vs h[1][2][3][4] below).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class Hash&lt;br /&gt;&lt;br /&gt;   def extract_keys&lt;br /&gt;&lt;br /&gt;      keys = []&lt;br /&gt;&lt;br /&gt;      each_pair do |k1, v1|&lt;br /&gt;&lt;br /&gt;         if v1.is_a?(Hash)&lt;br /&gt;&lt;br /&gt;            v1.each_pair { |k2, v2|&lt;br /&gt;               if !v2.is_a?(Hash) then keys &lt;&lt; [k1, k2]; next end&lt;br /&gt;            v2.each_pair { |k3, v3|&lt;br /&gt;               if !v3.is_a?(Hash) then keys &lt;&lt; [k1, k2, k3]; next end&lt;br /&gt;            v3.each_pair { |k4, v4|&lt;br /&gt;               if !v4.is_a?(Hash) then keys &lt;&lt; [k1, k2, k3, k4]; next end&lt;br /&gt;            v4.each_pair { |k5, v5|&lt;br /&gt;               if !v5.is_a?(Hash) then keys &lt;&lt; [k1, k2, k3, k4, k5]; next end&lt;br /&gt;            v5.each_pair { |k6, v6|&lt;br /&gt;               if !v6.is_a?(Hash) then keys &lt;&lt; [k1, k2, k3, k4, k5, k6]; next end&lt;br /&gt;               # add more v[n].each_pair ... loops to process more hash dimensions&lt;br /&gt;            } } } } }      # "}" * 5&lt;br /&gt;&lt;br /&gt;         else&lt;br /&gt;            keys &lt;&lt; [k1]&lt;br /&gt;         end&lt;br /&gt;&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      keys&lt;br /&gt;&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def all_values&lt;br /&gt;      extract_keys.map do |subar|&lt;br /&gt;         key = ""&lt;br /&gt;         subar.size.times { |i| key &lt;&lt; "[subar[#{i}]]" }&lt;br /&gt;         hash_str = "self" &lt;&lt; key &lt;&lt; " rescue nil"   # example: "self[subar[0]][subar[1]][subar[2]][subar[3]] rescue nil"&lt;br /&gt;         hash_value = eval(hash_str) &lt;br /&gt;      end&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#-------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   # Find every path and it's value in a Hash, http://snippets.dzone.com/posts/show/3565&lt;br /&gt;   # Author: Florian A&#223;mann&lt;br /&gt;&lt;br /&gt;   def each_path&lt;br /&gt;      raise ArgumentError unless block_given?&lt;br /&gt;      self.class.each_path(self) { |path, object| yield(path, object) }&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;   protected&lt;br /&gt;   #def self.each_path(object, path = '', &amp;block)&lt;br /&gt;   def self.each_path(object, path = [], &amp;block)   # alternative&lt;br /&gt;      if object.is_a?(Hash)&lt;br /&gt;         object.each do |key, value|&lt;br /&gt;            #self.each_path(value, "#{ path }#{ key }/", &amp;block)&lt;br /&gt;            self.each_path(value, [path , key].flatten, &amp;block)   # alternative&lt;br /&gt;         end&lt;br /&gt;      else &lt;br /&gt;         yield(path, object)&lt;br /&gt;      end&lt;br /&gt;   end &lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h = {"a"=&gt;"b", "c"=&gt;"d", 1=&gt;{2=&gt;{"e"=&gt;"f", 3=&gt;{4=&gt;"value"}}}} &lt;br /&gt;&lt;br /&gt;puts h[1][2].class          # Hash&lt;br /&gt;puts h[1][2]["e"].class     # String&lt;br /&gt;&lt;br /&gt;extracted_keys = h.extract_keys&lt;br /&gt;puts extracted_keys.inspect         # [["a"], [1, 2, "e"], [1, 2, 3, 4], ["c"]]&lt;br /&gt;&lt;br /&gt;puts h[1][2].has_key?("e")                 # true&lt;br /&gt;puts extracted_keys.include?([1, 2, "e"])  # true&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h = {700=&gt;{4=&gt;"value"}, "a"=&gt;"b", 3=&gt;{4=&gt;"value"}, "c"=&gt;"d", 1=&gt;{2=&gt;{"e"=&gt;"f", 3=&gt;{4=&gt;"value"}, 300=&gt;{4=&gt;"value"}}}} &lt;br /&gt;p h&lt;br /&gt;p h.extract_keys    #=&gt; [["a"], [1, 2, "e"], [1, 2, 300, 4], [1, 2, 3, 4], ["c"], [700, 4], [3, 4]]&lt;br /&gt;p h.all_values      #=&gt; ["b", "f", "value", "value", "d", "value", "value"]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#-----------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;paths = []&lt;br /&gt;complex_hash = Hash[&lt;br /&gt;  :a =&gt; { :aa =&gt; '1', :ab =&gt; '2' },&lt;br /&gt;  :b =&gt; { :ba =&gt; '3', :bb =&gt; '4' }&lt;br /&gt;]&lt;br /&gt;complex_hash.each_path { |path, value| paths &lt;&lt; [ path, value ] }&lt;br /&gt;&lt;br /&gt;p paths    # =&gt; [[[:b, :ba], "3"], [[:b, :bb], "4"], [[:a, :ab], "2"], [[:a, :aa], "1"]]&lt;br /&gt;puts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;h = {"a"=&gt;"b", "c"=&gt;"d", 1=&gt;{2=&gt;{"e"=&gt;"f", 3=&gt;{4=&gt;"value"}}}} &lt;br /&gt;h = {"a"=&gt;"b", "l" =&gt; lambda { |x| x+1 }, 1=&gt;{2=&gt;{"e"=&gt;"f", 3=&gt;{4=&gt;"value"}}}} &lt;br /&gt;h = {700=&gt;{4=&gt;"value"}, "a"=&gt;"b", nil =&gt; "NILVALUE", 3=&gt;{4=&gt;"value"}, "c"=&gt;"d", 1=&gt;{2=&gt;{"e"=&gt;"f", 3=&gt;{4=&gt;"value"}, 300=&gt;{4=&gt;"value"}}}} &lt;br /&gt;&lt;br /&gt;p h&lt;br /&gt;p h.extract_keys&lt;br /&gt;&lt;br /&gt;keys = []&lt;br /&gt;h.each_path { |path, value| keys &lt;&lt; path }&lt;br /&gt;p keys   # complete key sequences (with last key not pointing to another hash)&lt;br /&gt;&lt;br /&gt;paths = []&lt;br /&gt;h.each_path { |path, value| paths &lt;&lt; [ path, value ] }&lt;br /&gt;p paths   # complete key sequences plus values&lt;br /&gt;&lt;br /&gt;vals = []&lt;br /&gt;h.each_path { |path, value| vals &lt;&lt; value }&lt;br /&gt;p vals   # all values of complete key sequences&lt;br /&gt;&lt;br /&gt;p h.all_values   # same&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 12 Apr 2006 20:29:09 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1908</guid>
      <author>ntk ()</author>
    </item>
    <item>
      <title>Factorial in Scheme</title>
      <link>http://snippets.dzone.com/posts/show/1734</link>
      <description>;Calculate the factorial of a number&lt;br /&gt;;(factorial 5) = 1 * 2 * 3 * 4 * 5 = 120&lt;br /&gt;;(factorial 50) = 30414093201713378043612608166064768844377641568960512000000000000&lt;br /&gt;&lt;code&gt;&lt;br /&gt;(define factorial&lt;br /&gt;  (lambda (n)&lt;br /&gt;    (if (= n 0) 1&lt;br /&gt;        (* n (factorial (- n 1))))))&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 23 Mar 2006 12:59:22 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1734</guid>
      <author>willpost ()</author>
    </item>
    <item>
      <title>pass variable as hidden</title>
      <link>http://snippets.dzone.com/posts/show/1729</link>
      <description>pass variable as hidden field&lt;br /&gt;recursively handles array&lt;br /&gt;eg usage: &lt;br /&gt;foreach ($_REQUEST as $key =&gt; $val) &lt;br /&gt;  pass_hidden($key, $val);&lt;br /&gt;&lt;code&gt; &lt;br /&gt;function pass_hidden($key, $val) {&lt;br /&gt;  if (is_array($val)) {&lt;br /&gt;    foreach ($val as $k =&gt; $v) &lt;br /&gt;      pass_hidden("{$key}[{$k}]", $v);&lt;br /&gt;  } else {&lt;br /&gt;    ?&gt;&lt;input type="hidden" name="&lt;?=$key?&gt;" value="&lt;?=htmlspecialchars($val)?&gt;"&gt;&lt;br /&gt;    &lt;?&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 23 Mar 2006 01:37:50 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1729</guid>
      <author>reynardmh ()</author>
    </item>
    <item>
      <title>Memoizing functions in JavaScript</title>
      <link>http://snippets.dzone.com/posts/show/488</link>
      <description>Here's something I knocked together a fortnight ago because I wanted to see if I could produce Perl's Memoize.pm in JavaScript.&lt;br /&gt;&lt;br /&gt;Memoization is a method of increasing the speed of slow referentially transparent functions by caching their arguments and results. This trades a marginal amount of memory space for a potentially huge gain in speed.&lt;br /&gt;&lt;br /&gt;Take the canonical definition of the fibonacci sequence, for instance:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function fib(n) {&lt;br /&gt;    if (n &lt; 2) {&lt;br /&gt;        return n;&lt;br /&gt;    }&lt;br /&gt;    return fib(n - 1) + fib(n - 2);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;As you can guess, this quickly becomes quite slow once you start using numbers greater than around 20. Once you're dealing with numbers in the mid-thirties range, it cripples the computer.&lt;br /&gt;&lt;br /&gt;The solution is to memoize the function. You can either do it by hand:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var iterMemoFib = (function() {&lt;br /&gt;    var cache = [1, 1];&lt;br /&gt;    var fib = function(n) {&lt;br /&gt;        if (n &gt;= cache.length) {&lt;br /&gt;            for (var i = cache.length; i &lt;= n; i++) {&lt;br /&gt;                cache[i] = cache[i - 2] + cache[i - 1];&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return cache[n];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return fib;&lt;br /&gt;})();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Which is a wee bit of a pain and not exactly readable; or get the computer to do it for you:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;fib = fib.memoize();&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Due to technical (browser security) constraints, the arguments for memoized functions can only be arrays or scalar values. No objects.&lt;br /&gt;&lt;br /&gt;The code extends the Function object to add the memoization functionality. If the function is a method, then you can pass the object into memoize().&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Function.prototype.memoize = function() {&lt;br /&gt;    var pad  = {};&lt;br /&gt;    var self = this;&lt;br /&gt;    var obj  = arguments.length &gt; 0 ? arguments[i] : null;&lt;br /&gt;&lt;br /&gt;    var memoizedFn = function() {&lt;br /&gt;        // Copy the arguments object into an array: allows it to&lt;br /&gt;        // be used as a cache key.&lt;br /&gt;        var args = [];&lt;br /&gt;        for (var i = 0; i &lt; arguments.length; i++) {&lt;br /&gt;            args[i] = arguments[i];&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Evaluate the memoized function if it hasn't been&lt;br /&gt;        // evaluated with these arguments before.&lt;br /&gt;        if (!(args in pad)) {&lt;br /&gt;            pad[args] = self.apply(obj, arguments);&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return pad[args];&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    memoizedFn.unmemoize = function() {&lt;br /&gt;        return self;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return memoizedFn;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Function.prototype.unmemoize = function() {&lt;br /&gt;    alert("Attempt to unmemoize an unmemoized function.");&lt;br /&gt;    return null;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 22 Jul 2005 05:35:49 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/488</guid>
      <author>keith (Keith Gaughan)</author>
    </item>
  </channel>
</rss>
