2011-09-20 7 views
0

で「Y」プロパティ内のすべてのオブジェクトの「x」のプロパティを取得し、次の例を考えてみましょう:は再帰

<script> 
var McDuffFamily = { 
    name: "Jack McDuff I", 
    children: [ 
     { 
      name:"Jack McDuff II", 
      children: [ 
       { 
        name:"Jack McDuff III", 
        children: [ 
         { 
          name:"Jack McDuff IV" 
         }, 
         { 
          name:"Jonh McDuff I", 
          children: [ 
           { 
            name:"Jonh McDuff I", 
            children: [] 
           } 
          ] 
         } 
        ] 
       }, 
       { 
        name:"Shena McDuff" 
       } 
      ] 
     }, 
     { 
      name:"Poor bastard", 
      children: [ 
       { 
        name:"Citzen I", 
        children: [ 
         { 
          name:"Darth Vader" 
         } 
        ] 
       }, 
       { 
        name:"Citzen II", 
        children: [] 
       } 
      ] 
     } 
    ] 
}; 
</script> 

はすべて「ジャック・マクダフI」の子孫の名前を取得するための任意の痛みのない方法はありますか?

答えて

2

再帰を使用しない:奇妙な部分の

var tree =[McDuffFamily]; 
var kids = []; 
for (i=0; i < tree.length; i++) { 

    tree[i] && tree.push.apply(tree, tree[i].childrens) 
    kids.push(tree[i]); 
} 
kids; // all children 

内訳:

tree[i] && tree.push.apply(tree, tree[i].childrens); 

tree[i] &&は私がapplyを使用してtree[i].children

tree.push.apply(tree, tree[i].childrens);を呼び出すときtree[i]がnullでないことを確実にすることshort-circuit evaluationで使用されています私に電話することができますこの場合はArray.pushの関数で、任意の数の引数をtreeに指定します。その線は基本的にtree.push(child0, child1, ... childn);になります。

だから、tree.lengthは、現在の子供の子供の数によって増加しています。

+0

興味深いですが、正直なところ、どういう仕組みか分かりません – cvsguimaraes

+0

どちらの部分ですか?あなたが望むなら、私はそれに光を当てることができます – Joe

+0

tree [i] && tree.push.apply(tree、tree [i] .childrens) – cvsguimaraes

1
for(var names = [], i = 0, l = McDuffFamily.childrens.length; i < l; i++) { 
    names.push(McDuffFamily.childrens[i].name); 
} 

names; // ['Jack McDuff II', 'Poor bastard'] 

あなたは(ノードのようなまたはMooToolsのを使用して)環境を使用している場合は、[]あなたも行うことができ.reduceすることができます:

names = McDuffFamily.childrens.reduce(function(prev, curr) { 
    prev.push(curr.name); 
}, []); 

names; // ['Jack McDuff II', 'Poor bastard'] 

私は[] .reduceが立派に見えますが、それだと思います最も簡単な解決策は、単に基本的な再帰関数を使用することですより多くの課税

+3

私は彼が家族のツリー全体がJack McDuffの子供だけではないと思っています。子供のIEの子供。 –

+0

ああ、私の例はあまりありません.e – Marshall

2

です:

function traverse(parent, visit) { 
    var ii; 

    visit(parent.name); 

    for (ii = 0; ii < parent.children.length; ii += 1) { 
     traverse(parent.children[ii], visit); 
    } 
} 

初期VA lue of parentMcDuffFamilyであり、visitはノードにアクセスしたときに何をしたいのかを決める機能です。

+0

ここで最も速いクリーンな解決策です。ありがとう。 – cvsguimaraes

2

この関数は、家系図whitin指定された名前のすべての子孫を返します。

function getDescendants(family, name) 
{ 
    var result = []; 

    var iterate = function(node, isDescendant) 
    { 
     if(isDescendant) 
      result.push(node.name); 
     else 
      isDescendant = (node.name == name); 

     for(var i=0; i<node.children.length; i++) 
      iterate(node.children[i], isDescendant); 
    }; 

    iterate(family, false); 

    return result; 
} 

それはすべての子孫の名前を含む配列を返します。

PS:childrenは既に複数であるため、childrensの代わりにchildrenを書きました。