2016-08-29 10 views
0

だが、私はそうのようなネストされたオブジェクトがあるとしましょう:データ構造のようなツリーのすべてのパスをトレースするには?

{ 
    label: 'parent', 
    eyeColor: 'brown', 
    kids: [ 
    { 
     label: 'kid_0', 
     eyeColor: 'brown', 
     kids: [ 
     { 
      label: 'kid_0_0', 
      eyeColor: 'green', 
      kids: [] 
     }, 
     { 
      label: 'kid_0_1', 
      eyeColor: 'brown', 
      kids: [ 
      { 
       label: 'kid_0_1_0', 
       eyeColor: 'brown', 
       kids: [] 
      } 
      ] 
     } 
     ], 
    }, 
    { 
     label: 'kid_1', 
     eyeColor: 'brown', 
     kids: [ 
     { 
      label: 'kid_1_0', 
      eyeColor: 'brown', 
      kids: [] 
     } 
     ], 
    }, 
    { 
     label: 'kid_2', 
     eyeColor: 'green', 
     kids: [] 
    } 
    ] 
}; 

私はすべてのユニークなパスを保存したい場合は、どのように私は再帰的に行うのでしょうか?私は多くの試みを試みましたが、ユニークなパスを得ることができません(私のパスは前のパスの上に構築されます)。

だから私の予想される出力は次のようになります。

[ 
    ['parent', 'kid_0', 'kid_0_0], 
    ['parent', 'kid_0', 'kid_0_1, kid_0_1_0], 
    ['parent', 'kid_1', 'kid_1_0], 
    ['parent', 'kid_2] 
] 

しかし、私は、私はbrown以外eyeColorと子供またはノードを見つけたときのパスを停止したい場合、パスはそこに停止します。そして、何次取得するために変更する必要があります:これは今ある私の現在のコード、B/Cの最大コールスタックのうち、エラーが-INGのさ

[ 
    ['parent', 'kid_0', 'kid_0_1, kid_0_1_0], 
    ['parent', 'kid_1', 'kid_1_0], 
] 

var printPaths = function(node, color) { 
    var paths = []; 

    var trackPath = function(obj, feature, path) { 
    if (obj.eyeColor === 'brown') { 
     path.push(node.label); 
    } else if (obj.eyeColor !== 'brown') { 
     paths.push(path); 
    } else if (obj.kids.length === 0) { 
     paths.push(path); 
    } 

    for (var i = 0; i < obj.kids.length; i++) { 
     trackPath(obj.kids[i], feature, path) 
     path.pop(); 
    } 
    }; 

    trackPath(node, color, []); 
    return paths; 
} 
+0

動作しなくても試してみてください。 – Bergi

+0

@Bergi私は壊れたコードを投稿しました。私は経験豊富なプログラマーが問題にどのようにアプローチしているのかを見たいと思っていたので、投稿することを躊躇しました。 – AlanH

+0

このアプローチは、[配列は参照値であり、明示的にコピーする必要がある]という点を除いて、きれいに見えます(http://stackoverflow.com/q/7486085/1048572)。そこで、 '.pop()'呼び出しを落とし、その代わりに再帰呼び出しを 'trackPath(obj、feature、path.slice())'にします。 – Bergi

答えて

1

あなたのアプローチはほとんど問題なく、唯一の問題はassignment or argument passing doesn't copy arraysです。再帰にslice()コールを導入:ここ

function printPaths(node, color) { 
    var paths = []; 

    function trackPath(obj, feature, path) { 
    if (obj.eyeColor !== feature) { // found target 
     paths.push(path); 
     return; 
    } // else continue 
    path.push(obj.label); 

    for (var i = 0; i < obj.kids.length; i++) { 
     trackPath(obj.kids[i], feature, path.slice()); 
//          ^^^^^^^^ 
    } 
    } 

    trackPath(node, color, []); 
    return paths; 
} 
+0

Hm。面白い。この解決法は機能しませんか? – AlanH

+0

@AlanH: 'フィーチャー'のものは違っていました。私の編集後、あなたの答えと同じように動作するはずです – Bergi

0

が私のアプローチですが、私はあなたのロジックだけでなく、スライス

var printPaths = function(node, color) { 
    var paths = []; 

    var trackPath = function(obj, feature, path) { 
    //debugger; 
    path.push(obj.label); 

    if (obj.eyeColor === 'brown') { 
     if (obj.kids.length == 0) { 
     paths.push(path.slice()); 
     } 
     else { 
     for (var i = 0; i < obj.kids.length; i++) { 
      trackPath(obj.kids[i], feature, path); 
     } 
     } 
    } 


    path.pop(); 
    }; 

    trackPath(node, color, []); 
    return paths; 
} 
0

これは私がなってしまったソリューションでしたを使用して、使用アレイのコピーを書き換えなければなりませんでした働く@Bergiの助けを借りていましたが、彼の解決策は私が必要とするものではありません。この解決策は、私が書いたすべてのテストを通過します。

var printPaths = function(node, color) { 
    var paths = []; 

    var trackPath = function(obj, feature, path) {  
    // if the current node has the desired property, push that 
    // to the current path, then continue checking checking 
    // if there are any children (two if statements down) 
    if (obj.eyeColor === feature) { 
     path.push(obj.label); 
    } 
    // if we encounter a path that isn't our desired property, 
    // don't push the current node on to the current path, but instead 
    // just push the failed path, and return, so that it doesn't 
    // continue to check 
    if (obj.eyeColor !== feature) { 
     paths.push(path); 
     return; 
    } 
    // if we're at a leaf node, i.e we had a full successful path 
    // (everyone had brown eyes) 
    if (obj.kids.length === 0) { 
     paths.push(path); 
    } 

    for (var i = 0; i < obj.kids.length; i++) { 
     trackPath(obj.kids[i], feature, path.slice()) 
    } 
    }; 

    trackPath(node, color, []); 
    return paths; 
} 
関連する問題