0

我整天都在反对这个。是时候换眼了。

我有一个使用祖先 gem 的树结构模型。效果很好,调用TreeNode.arrange返回一个整洁的小哈希,它是一个嵌套树。问题是由于缺乏更好的描述,我正在寻找“扁平树”。例如:

Node1
Node2
Node3
  Node4
  Node5
  Node6
    Node7
    Node8
Node9

相对于更传统的

Node1
  Node2
   Node3...

所以换句话说,如果有一个分支点(多个孩子),我只想“缩进”我的树。我认为最好的方法是递归函数。我已经尝试了几种变体,但我只是在这个上画了一个空白:-\

def walk_until_fork(tree_hash,&blk)
   tree_hash.each do |node,children| 
    yield node.title
    if children.keys.length > 1
      #fork point
      children.each do |subnode,grandchilden|
        walk_until_fork(grandchilden,&blk)
        yield subnode.title       
      end
    else
      walk_until_fork(children,&blk)
    end
  end
end

调用该测试代码的结果是分叉点最终位于输出的底部:-\

我真正想看到的是这样的散列结构,但唯一应该有孩子的键是发生分支的地方(一个分支在当前级别继续,并且在该分支之后的每个 n 分支)。

我不确定我是否清楚。如果需要,我会澄清任何问题。

4

2 回答 2

0

删除了我所有的东西,然后用一种新的方法重新开始。稍后我很可能会对其进行重构,但这是基本思想。

def walk_until_fork(tree_hash, root_node = nil)
  root_node ||= ActiveSupport::OrderedHash.new
  tree_hash.each do |node,children|
    more_than_one = false
    parent_node = root_node[node] = ActiveSupport::OrderedHash.new
    children.each do |k,v|
      fork_node = more_than_one ? parent_node : root_node
      walk_until_fork({k => v},fork_node)
      more_than_one = true
    end
  end
  root_node
end

然后我打电话给:

walk_until_fork(self.arrange)

代码将散列引用传递给当前根,将其更改为新散列,只有一个以上的孩子。

于 2013-02-05T08:24:17.663 回答
-1

您可以在 CSS 中指定要将其限制为多少级嵌套。将其限制为 3 个级别,因为您表示您的 CSS 中将包含以下内容。

.nested_messages {
      margin-left: 30px;
    }

    .nested_messages .nested_messages .nested_messages .nested_messages{
      margin-left: 0;
    }

在上面的这个 CSS 中,您只能缩进 3 级(在您的页面中使用相关代码。在 3 级项目不再缩进之后。我只是在这里显示 CSS,您需要在视图中添加额外的代码。

Ryan Bates 在此 Railscast 中对此进行了介绍,并提供了完整的代码示例。你应该能够一步一步地走过它。

http://railscasts.com/episodes/262-trees-with-ancestry

于 2013-02-05T20:27:48.597 回答