<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: dimension code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Tue, 19 Aug 2008 11:10:33 GMT</pubDate>
    <description>DZone Snippets: dimension code</description>
    <item>
      <title>Extracting all subarray indices from a multi-dimensional array</title>
      <link>http://snippets.dzone.com/posts/show/1956</link>
      <description>Note the use of Array#fetch to define return values for missing indices!&lt;br /&gt;Example: ar = []; x = ar.fetch(5, [])  returns an empty array for non-existing index 5.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class Array&lt;br /&gt;&lt;br /&gt;   def subar_indices(ar=[], temp=[])&lt;br /&gt;      temp = temp.dup&lt;br /&gt;      self.each_with_index { |item, index| &lt;br /&gt;         if item.class == Array&lt;br /&gt;            temp &lt;&lt; index&lt;br /&gt;            ar &lt;&lt; temp&lt;br /&gt;            ar = item.subar_indices(ar, temp)&lt;br /&gt;         end&lt;br /&gt;      }&lt;br /&gt;      ar.uniq&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   def extract_subar_indices&lt;br /&gt;      subarray_indices = self.subar_indices  # subarray_indices is a two-dimensional array&lt;br /&gt;      # puts subarray_indices.inspect&lt;br /&gt;      &lt;br /&gt;      return subarray_indices if subarray_indices.empty?&lt;br /&gt;&lt;br /&gt;      first_subar = subarray_indices.shift   # the first subarray contains all two-dimensional subarray indices                &lt;br /&gt;&lt;br /&gt;      subarray_indices.each do |subar|&lt;br /&gt;         subar_size = subar.size&lt;br /&gt;         str = ""&lt;br /&gt;         count = -1&lt;br /&gt;         (subar_size - 1).times { count += 1; str &lt;&lt; ".fetch(subar[#{count}], [])" }&lt;br /&gt;         str &lt;&lt; ".fetch(subar[#{count + 1}], {}"&lt;br /&gt;         str = "self" &lt;&lt; str&lt;br /&gt;         if eval(str).class == Hash then subar.shift; redo end&lt;br /&gt;      end&lt;br /&gt;&lt;br /&gt;      first_subar.reverse.each do |item| subarray_indices.unshift([item]) end&lt;br /&gt;      subarray_indices&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;array = [1, 2, [3, 4, [5, 6]], 7, 8, [9]]&lt;br /&gt;&lt;br /&gt;indices = array.extract_subar_indices&lt;br /&gt;&lt;br /&gt;puts indices.inspect  # [[2], [5], [2, 2]]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 22 Apr 2006 20:14:52 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1956</guid>
      <author>ntk ()</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>Creating multi-dimensional hashes in Ruby</title>
      <link>http://snippets.dzone.com/posts/show/1850</link>
      <description>The use of var = keys.shift (instead of var = keys_clone || keys.shift) will produce an alternative output!&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class Hash&lt;br /&gt;  def mdh(*mkeys)&lt;br /&gt;     value = mkeys.pop&lt;br /&gt;     count = 0&lt;br /&gt;     mdhash = lambda { |*keys|&lt;br /&gt;                   count += 1&lt;br /&gt;                   keys_clone = keys.clone if count == 1 # keys_clone will return nil for count &gt; 1 in Hash.new&lt;br /&gt;                   Hash.new(var = keys_clone || keys.shift).update(var =&gt; mdhash[*keys] || value) unless keys.empty? &lt;br /&gt;                 }&lt;br /&gt;     mdhash.call(*mkeys)&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;h = Hash.new.mdh(1, 2, 3, 4, "value")&lt;br /&gt;&lt;br /&gt;puts h.inspect  # {[1, 2, 3, 4]=&gt;{1=&gt;{2=&gt;{3=&gt;{4=&gt;"value"}}}}}&lt;br /&gt;&lt;br /&gt;k = [1, 2, 3, 4]&lt;br /&gt;puts h.has_key?(k)&lt;br /&gt;puts h[k][k[0]][k[1]][k[2]][k[3]]  # value&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;     &lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 06 Apr 2006 16:09:52 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1850</guid>
      <author>ntk ()</author>
    </item>
    <item>
      <title>Creating multi-dimensional arrays in Ruby</title>
      <link>http://snippets.dzone.com/posts/show/1830</link>
      <description>Based on a one-liner posted at:&lt;br /&gt;http://aspn.activestate.com/ASPN/Mail/Message/ruby-talk/2852734&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;class Array&lt;br /&gt;&lt;br /&gt;   def mda(*mds)&lt;br /&gt;&lt;br /&gt;      count = -1&lt;br /&gt;&lt;br /&gt;      mdarray = lambda { |*ds| &lt;br /&gt;        Array.new( ds.shift || 0 ).collect {&lt;br /&gt;            x = mdarray[*ds] unless ds.empty?&lt;br /&gt;            if x == nil then count += 1; x = self.at(count); end&lt;br /&gt;            x&lt;br /&gt;            }&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      mdarray.call(*mds)    &lt;br /&gt;&lt;br /&gt;   end&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ar1 = (1..24).to_a    # input data&lt;br /&gt;&lt;br /&gt;ar2 = ar1.mda(1, 2, 3, 4)   # note: 1 x 2 x 3 x 4 = 24 &lt;br /&gt;puts ar2.inspect&lt;br /&gt;&lt;br /&gt;puts ar2[0..0][0..1][0..2][0..3].inspect    # returns entire ar2&lt;br /&gt;puts ar2[0][1][2][0..3].inspect             # returns last subarray &lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;# extracting subarrays&lt;br /&gt;ar = []&lt;br /&gt;ar2.each { |a| a.each { |b| b.each { |c| ar &lt;&lt; c if c.last &gt; 6 } } }&lt;br /&gt;puts ar.inspect&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# extracting only the first subarray that meets the if-condition&lt;br /&gt;ar = []&lt;br /&gt;ar &lt;&lt; catch(:val) { ar2.each { |a| a.each { |b| b.each { |c| throw(:val, c) if c.last &gt; 6 }}} }&lt;br /&gt;puts ar.inspect&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 02 Apr 2006 21:20:23 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/1830</guid>
      <author>ntk ()</author>
    </item>
  </channel>
</rss>
