title: Recursively create hierarchical hash from Mongo collection in Ruby
body: <p>I am trying to create a hash that looks like this:</p>
  
  <pre><code>{"difficulty"=&gt;{"easy"=&gt;{}, "normal"=&gt;{}, "hard"=&gt;{}}, "terrain"=&gt;{"snow"=&gt;{"sleet"=&gt;{}, "powder"=&gt;{}}, "jungle"=&gt;{}, "city"=&gt;{}}}
  </code></pre>
  
  <p>From a MongoDB collection which is and enumerable list of hashes that looks like this:</p>
  
  <pre><code>{
  "_id" : "globalSettings",
  "groups" : [
      "difficulty",
      "terrain"
  ],
  "parent" : null,
  "settings" : {
      "maxEnemyCount" : 10,
      "maxDamageInflicted" : 45,
      "enemyHealthPoints" : 40,
      "maxEnemySpeed" : 25,
      "maxPlayerSpeed" : 32,
      "lightShader" : "diffuse",
      "fogDepth" : 12,
      "terrainModifier" : 9
  }
  },
  {
  "_id" : "difficulty",
  "groups" : [
      "easy",
      "normal",
      "hard"
  ],
  "parent" : "globalSettings",
  "settings" : {
  
  }
  }
  {
  "_id" : "terrain",
  "groups" : [
      "snow",
      "jungle",
      "city"
  ],
  "parent" : "globalSettings",
  "settings" : {
  }
  }
  {
  "_id" : "snow",
  "groups" : [
      "sleet",
      "powder"
  ],
  "parent" : "terrain",
  "settings" : {
      "fogDepth" : 4
  }
  }
  {
  "_id" : "jungle",
  "groups" : [ ],
  "parent" : "terrain",
  "settings" : {
      "terrainModifier" : 6
  }
  }
  {
  "_id" : "city",
  "groups" : [ ],
  "parent" : "terrain",
  "settings" : {
      "lightShader" : "bumpedDiffuse"
  }
  }
  {
  "_id" : "easy",
  "groups" : [ ],
  "parent" : "difficulty",
  "settings" : {
      "maxEnemyCount" : 5
  }
  }
  {
  "_id" : "normal",
  "groups" : [ ],
  "parent" : "difficulty",
  "settings" : {
  
  }
  }
  {
  "_id" : "hard",
  "groups" : [ ],
  "parent" : "difficulty",
  "settings" : {
      "maxEnemyCount" : 20
  }
  }
  {
  "_id" : "sleet",
  "groups" : [ ],
  "parent" : "snow",
  "settings" : {
      "fogDepth" : 2
  }
  }
  {
  "_id" : "powder",
  "groups" : [ ],
  "parent" : "snow",
  "settings" : {
      "terrainModifier" : 2
  }
  }
  </code></pre>
  
  <p>Every time I try to write the function, I get stuck when setting the parent of the group.  How do I recurse, yet keep track of the path of hierarchy?</p>
  
  <p>The closest I've come is with this:</p>
  
  <pre><code>def dbCurse(nodes, parent = nil)
    withParent, withoutParent = nodes.partition { |n| n['parent'] == parent }
    withParent.map do |node|
      newNode={}
      newNode[node["_id"]]={}
      newNode[node["_id"]].merge(node["_id"] =&gt; dbCurse(withoutParent, node['_id']))
    end
  end
  </code></pre>
  
  <p>which gives me a crazy mix of arrays and hashes:</p>
  
  <pre><code>{"globalSettings"=&gt;[{"difficulty"=&gt;[{"easy"=&gt;[]}, {"normal"=&gt;[]}, {"hard"=&gt;[]}]}, {"terrain"=&gt;[{"snow"=&gt;[{"sleet"=&gt;[]}, {"powder"=&gt;[]}]}, {"jungle"=&gt;[]}, {"city"=&gt;[]}]}]}
  </code></pre>
  
  <p>I think the arrays are getting mixed in there from the #map but I'm not sure how to get rid of them to get the clean hash of hashes I show at the top of my question.</p>
  
  <p>Thank you,
  David</p>