如果我有一个自引用的Topic类,并且我想递归遍历所有的子主题,那么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
答案 0 :(得分: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
答案 1 :(得分: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
这样做的另一个好处是,您可以使用由topics
和parent
装饰器创建的has_many
和belongs_to
方法,以便轻松浏览主题树。< / p>
答案 2 :(得分:0)
我不知道Ruby,但是如果你有哈希表和链表实现方便我会这样做(在Java-ish伪代码中):
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()会针对每个主题执行您需要做的任何事情。