Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There is a <a href="http://en.wikipedia.org/wiki/Tree_traversal" rel="nofollow noreferrer">wikipedia article</a> on tree traversal which shows different alternatives to the recursive solution you are using. It may be tricky to use them in your specific case, but it should be possible.</p> <p>However, my question to you is, is there a specific reason you want to use iteration instead of recursion? I don't think any of the iterative solutions will be nearly as clean. Are your trees so big that you are running out of stack space (they would have to be pretty big)? Otherwise, I'm not so sure an iterative solution will really be faster.</p> <p>I see one potential for improvement though, if you are seeing performance issues... but I don't know rails, so I'm not sure if it is accurate:</p> <p>Does the find method return a new array? If so, you probably want to invoke .collect! instead of .collect, because if find creates an array, you are just creating an array and then throwing it away to the call to collect (which also creates an array), which surely is not going to be very efficient and may slow you down a lot if you have a big tree there.</p> <p>So </p> <pre><code>{ node.name =&gt; node.products.find(:all).collect(&amp;:name) }.to_json </code></pre> <p>might become</p> <pre><code>{ node.name =&gt; node.products.find(:all).collect!(&amp;:name) }.to_json </code></pre> <p>EDIT: Also, it may be more efficient to create your hash of hashes, and then convert the whole thing to json in 1 fell swoop, rather than converting it piecemail like you are doing.</p> <p>So</p> <pre><code>class Node &lt; ActiveRecord::Base has_many :products def json_hash if children.size &gt; 0 children.collect { |node| { node.name =&gt; node.json_hash }.to_json else { node.name =&gt; node.products.find(:all).collect!(&amp;:name) }.to_json end end end </code></pre> <p>might become</p> <pre><code>class Node &lt; ActiveRecord::Base has_many :products def json_hash to_hash.to_json end def to_hash if children.size &gt; 0 children.collect { |node| { node.name =&gt; node.to_hash } else { node.name =&gt; node.products.find(:all).collect!(&amp;:name) } end end end </code></pre> <p>Whether this works and is more efficient I leave as an exercise for you ;-)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload