2008-09-03 20 views
1

再帰を使用せずにRuby on Railsのacts_as_nested_set内の任意のノードからJSONハッシュを返す迅速かつきれいな方法はありますか?Rubyはacts_as_nested_setを再帰せずに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 

答えて

2

は、使用している再帰的な解決策に異なる選択肢を示し、ツリートラバーサルにwikipedia articleあり:

はここで参照のための再帰的なソリューションです。あなたの特定のケースでそれらを使用するのは難しいかもしれませんが、可能でなければなりません。

しかし、私の質問は、再帰の代わりに反復を使用する特定の理由はありますか?私は反復的な解決策のどれもがきれいになるとは思わない。あなたの木はとても大きいので、スタックスペースが足りなくなっています(彼らはかなり大きくなければなりません)?そうでなければ、反復的な解決策が本当に速くなるとは確信していません。

あなたはパフォーマンスの問題を見ている場合、私は、しかし改善のための1つの可能性を参照してください...しかし、私はレールを知らないので、私はそれが正確であるかどうかわからないんだけど:

は、findメソッドの戻り値aをい新しい配列?もしそうなら、あなたはおそらく.collectを起動したいでしょう! .collectの代わりに.collectを使用すると、配列が作成されただけで配列を作成してから(配列を作成する)コールに投げ捨てるだけです。効率的ではなく、遅くなる可能性がありますそこに大きな木があると、たくさんのことがあります。

ので

{ node.name => node.products.find(:all).collect(&:name) }.to_json 

{ node.name => node.products.find(:all).collect!(&:name) }.to_json 

EDITなる可能性があります:また、ハッシュのあなたのハッシュを作成する方が効率的であってもよく、その後、一挙に落ちた1で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 

は、この作品と私はあなたが

+0

幸いですが、私はこれを行うには反復的でファンシーなRubyの方法を探していました。 – hoyhoy

1

JSONifierを;-)ための練習として残して、より効率的であるかどうか

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 

になるかもしれません!

node.to_json(:include=>{:products=>{:include=>:product_parts}}) 
関連する問題