2009-09-14 69 views
0

如果我有一個自我指涉的主題類,我想通過我所有的子主題的遞歸循環,這將是一個很好的Ruby的方式來做到這一點:如何通過自引用子主題進行遞歸搜索?

@category.topics.all(:parent_id => topic.id).each do |subtopic| 
    subtopic.delete_tags 
    @category.topics.all(:parent_id => subtopic.id).each do |subsubtopic| 
    subsubtopic.delete_tags 
     @category.topics.all(:parent_id => subsubtopic.id).each do |subsubsubtopic| 
     subsubtopic.delete_tags 
      @category.topics.all(:parent_id => subsubsubtopic.id).each do |subsubsubsubtopic| 
      subsubsubtopic.delete_tags 
      end 
     end 
    end 
end 

回答

1

像這樣的事情?

class Topic 
    def delete_subtopic_tags 
    all(:parent_id => self.id).each do |subtopic| 
     subtopic.delete_subtopic_tags 
     subtopic.delete_tags 
    end 
    end 
end 
+0

這會進入無限循環嗎? – jprete 2009-09-14 22:07:08

+0

如果數據庫中存在任何與'parent_id'相同的主題,那麼它們會。 – rcoder 2009-09-14 22:10:18

+1

@jprete:如果某個話題是自身的一個子話題,那它只會是無限的。但是這本身就像是一個錯誤。否則遞歸會在到達沒有子主題的主題時結束。但它似乎應該是':parent_id => self.id'。 – Chuck 2009-09-14 22:17:28

1

這是一個ActiveRecord模型類嗎?如果是這樣,你應該能夠使用類似下面的代碼通過子對象乾淨遞歸:

class Topic 
    has_many :topics 
    belongs_to :parent, :classname => "Topic", :foreign_key => 'parent_id' 

    # ...other model class logic... 
    def delete_tags_recursive 
    delete_tags 
    topics.each {|subtopic| subtopic.delete_tags_recursive } 
    end 
end 

這有讓您使用由has_manybelongs_to裝飾,以創建topicsparent方法的額外好處輕鬆走過話題樹。

0

我不知道Ruby的,但如果你有哈希表和鏈接列表實現方便我會做這樣的事情(在Java中上下的僞代碼):

Topic currentTopic = topic; 
list.add(currentTopic); 
hashtable.add(currentTopic); 
while (list.empty() == false) { 
    for (Topic t : currentTopic.getSubtopics()) { 
     if (hashtable.contains(t) == false) { 
      list.add(t); 
      hashtable.add(t); 
     } 
    } 
    visit(currentTopic); 
    list.remove(currentTopic); 
    currentTopic = list.getFirst(); 
} 

這裏的主要觀點是保留散列表列表,以便您可以輕鬆確保您永遠不會訪問兩次主題。除此之外,它實質上是breadth-first search的實現。 visit()爲每個單獨的主題做你需要做的任何事情。