使用している再帰的なソリューションに代わるさまざまな方法を示すツリー トラバーサルに関するウィキペディアの記事があります。特定のケースでそれらを使用するのは難しいかもしれませんが、可能でなければなりません。
ただし、私の質問は、再帰の代わりに反復を使用したい特定の理由はありますか? 反復的な解決策のいずれも、ほぼクリーンになるとは思いません。ツリーが大きすぎて、スタック スペースが不足していませんか (かなり大きくなければなりません)。そうでなければ、反復ソリューションが本当に高速になるかどうかはわかりません。
ただし、パフォーマンスの問題が発生している場合は、改善の可能性が1つあります...しかし、レールを知らないので、それが正確かどうかはわかりません:
find メソッドは新しい配列を返しますか? もしそうなら、あなたはおそらく .collect! を呼び出したいと思うでしょう! .collect の代わりに、find が配列を作成する場合、単に配列を作成し、それを collect の呼び出し (配列も作成する) に捨てるだけなので、これは非常に効率的ではなく、速度が低下する可能性があります。そこに大きな木があればたくさん。
そう
{ node.name => node.products.find(:all).collect(&:name) }.to_json
になるかもしれません
{ node.name => node.products.find(:all).collect!(&:name) }.to_json
EDIT:また、ハッシュのハッシュを作成してから、すべてを一気にjsonに変換する方が、あなたがやっているように断片的に変換するよりも効率的かもしれません。
そう
class Node < ActiveRecord::Base
has_many :products
def json_hash
if children.size > 0
children.collect { |node| { node.name => node.json_hash }.to_json
else
{ node.name => node.products.find(:all).collect!(&:name) }.to_json
end
end
end
になるかもしれません
class Node < ActiveRecord::Base
has_many :products
def json_hash
to_hash.to_json
end
def to_hash
if children.size > 0
children.collect { |node| { node.name => node.to_hash }
else
{ node.name => node.products.find(:all).collect!(&:name) }
end
end
end
これが機能し、より効率的であるかどうかは、演習として残します;-)