0

私は一日中これに頭を悩ませてきました。新しい目の時間。

祖先の宝石を使用したツリー構造のモデルがあります。うまく機能し、呼び出す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

そのテスト コードを呼び出した結果、フォーク ポイントが出力の一番下になります :-\

私が本当に見たいのはそのようなハッシュ構造ですが、子を持つべき唯一のキーは分岐が発生した場所です (1 つの分岐はその現在のレベルで継続し、その後の各 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 で制限するネストのレベル数を指定できます。CSSに次のものがあることを示しているように、3つのレベルに制限するには。

.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 に答える