2016-10-05 14 views
2

私は以下のようなオブジェクトを持っており、ツリー内の各サブオブジェクトに1つのプロパティを追加する方法を探しています。つまり、0からnまでカウントアップするオブジェクトに数値を追加します。再帰的な関数を使ってオブジェクトをたどることができるのは分かっていますが、可変スコープがあるため、単純な増分変数を使用してツリーを通過するまでカウントアップすることはできません。ネストされたオブジェクトツリー内のJavascriptオブジェクトに連続番号を追加

現在のオブジェクト:

var tree = [ 
{ 
    name: 'a', 
    children: [] 
},{ 
    name: 'b', 
    children: [ 
     { 
      name: 'c', 
      children: [] 
     } 
    ] 
}, 
{ 
    name: 'd', 
    children: [ 
     { 
      name: 'e', 
      children: [ 
       { 
        name: 'f', 
        children: [] 
       }, 
       { 
        name: 'g', 
        children: [] 
       } 
      ] 
     } 
    ] 
} 
]; 

所期の目的:

var tree = [ 
{ 
    name: 'a', 
    number: 0, 
    children: [] 
},{ 
    name: 'b', 
    number: 1, 
    children: [ 
     { 
      name: 'c', 
      number: 2, 
      children: [] 
     } 
    ] 
}, 
{ 
    name: 'd', 
    number: 3, 
    children: [ 
     { 
      name: 'e', 
      number: 4, 
      children: [ 
       { 
        name: 'f', 
        number: 5, 
        children: [] 
       }, 
       { 
        name: 'g', 
        number: 6, 
        children: [] 
       } 
      ] 
     } 
    ] 
} 
]; 
+0

あなたの関数がその作業を行うために特定の値を必要とする場合は、それをパラメータとして渡します。これはすべてのスコープの問題を取り除きます。 – CBroe

+0

また、再帰レベルに関係なくインクリメントするのが問題になる場合は、再帰的に呼び出される関数のスコープ内にある変数を使用してください。 – CBroe

答えて

1

あなただけ再帰機能のカウンタ変数外に設定したループオブジェクトの前にそれをインクリメントする必要があります。

var tree = [{"name":"a","children":[]},{"name":"b","children":[{"name":"c","children":[]}]},{"name":"d","children":[{"name":"e","children":[{"name":"f","children":[]},{"name":"g","children":[]}]}]}]; 
 

 
function addNumber(input) { 
 
    var counter = 0; 
 

 
    function rec(data) { 
 
    data.forEach(function(e) { 
 
     if (typeof e == 'object' && !Array.isArray(e)) { 
 
     e.number = counter++; 
 
     for (var p in e) { 
 
      if (typeof e[p] == 'object') rec(e[p]) 
 
     } 
 
     } 
 
    }) 
 
    } 
 
    rec(input) 
 
} 
 

 
addNumber(tree); 
 
console.log(tree)

+0

forEachループの最後にelse ifステートメントが必要ですか?ループに入る各要素「e」は常に配列ではなくオブジェクトになります。 –

+0

私の答えは更新されていません。 –

3

あなたはカウンターの範囲で上げる問題はまた、あなたの再帰関数を持ってその中に閉鎖、カウンタを定義することによって解決することができます。

function numberNodes(tree, n = 0) { 
 
    return (function recurse(children) { 
 
     return children.map(node => Object.assign({}, node, { 
 
      number: n++, 
 
      children: recurse(node.children) 
 
     })); 
 
    })(tree); 
 
} 
 
// Sample data 
 
var tree = [{ name: 'a', children: []}, 
 
      { name: 'b', children: 
 
       [{ name: 'c', children: []}]}, 
 
      { name: 'd', children: 
 
       [{ name: 'e', children: 
 
        [{ name: 'f', children: []}, { name: 'g', children: []}]}]}]; 
 

 
// Return tree with numbers added: 
 
tree = numberNodes(tree); 
 

 
// Output result 
 
console.log(tree);

(注)この機能は、唯一の戻り値が追加されたプロパティを持っている、あなたはそれを渡すツリーを変異させていないこと:ここでは

があることないES6機能です。したがって、これは機能プログラミングのやり方です。

+0

私の場合はソースオブジェクトを変更しても問題ありませんが、これはおそらくこの問題を解決するためのより良いルートです。また、匿名関数、マップ関数、再帰関数がどのように相互作用しているかは、今のところ私が少し超えているので、私は本をもっと打つ必要があります。 –

関連する問題