2008-09-03 128 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。在你的具体情况下使用它们可能会很棘手,但它应该是可能的。

但是,我的问题是,是否有一个特定的原因,你想使用迭代而不是递归?我认为任何迭代解决方案都不会很干净。你的树太大了以至于你没有足够的空间(它们必须非常大)?否则,我不太确定迭代解决方案真的会更快。

我看到一个潜在的改进不过,如果你看到性能问题...但我不知道铁轨,所以我不知道这是否是准确的:

是否find方法返回一个新阵列?如果是这样,你可能想要调用.collect!而不是.collect,因为如果find创建一个数组,你只是创建一个数组,然后将它扔到调用来收集(这也会创建一个数组),这肯定不会非常高效,并且可能会减慢你的速度很多,如果你有一棵大树。

所以

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

可能成为

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

编辑:另外,它可能是更有效的创建你的哈希散列值,然后转换整个事情在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 

可能成为

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 

这是否可行,更有效,我离开为您;-)

+0

好的答案,但我正在寻找更多的迭代或花式的Ruby方式来做到这一点。 – hoyhoy 2008-09-12 08:01:52

1

JSONifier的锻炼!

node.to_json(:include=>{:products=>{:include=>:product_parts}}) 
相关问题