2017-08-27 6 views
0

私はループこの再帰関数には、本当にグローバル変数を使用する必要がありますか?

function deepFindGroup(groupName, currentGroup) { 
    console.log("Testing"); 
    for (e in currentGroup) { 

     if (currentGroup[e].intName == groupName) { 
      console.log(currentGroup[e]["Members"]); 
      return currentGroup[e]["Members"]; 
     } else if (currentGroup[e]["Members"]) { 
      return deepFindGroup(groupName, currentGroup[e]["Members"]); 
     } 
    } 
} 

ための私が意味のreturn文を持つすべての可能性を扱うことができないようであることを起こる再帰関数を持っています。たとえば、currentGroup [e] .intNameがgroupNameと等しくなく、そのブランチの子がメンバープロパティを持っていない(この場合、子はまったくありません)。それはundefinedを返して終わります。私が考えることができる唯一の解決策は、グローバル変数を作ることです、私はそれを回避しようとしています。

編集: この関数は、ツリー内の特定の枝を返すことになっています。ツリーは、 "Members"を含むオブジェクト(intNameプロパティを持つオブジェクト)で構成され、それ自体が他のメンバを含むオブジェクトになります。メンバーには何も含めることはできませんが、依然としてintNameを持っています。

はそのように見える:1つのブランチが発見が得られない場合

Gengroup_1--intName: Gengroup_1 
      | 
      --Members-- nochild -- intName: nochild 
        | 
        --Gengroup_2--intName: Gengroup2 
           | 
           --Members-- object -- intName: object 
              | 
              -- anotherObject -- intName: anotherObject 
+0

する必要がある機能は何ですか? – Ryan

+0

ツリー内の特定のブランチの位置を返す –

+1

より具体的に、してください。とにかく、何も見つからなかったことを知らせる価値(例えば、「ヌル」)と、子供の検索から戻る前にそれを確認する価値が必要になるでしょう。 – Ryan

答えて

1

機能を入力するときに何かが見つかった際に、反復を停止し、resultを定義します。マッチしたグループのcurrentGroup[e]["Members"]undefinedとき

function deepFindGroup(groupName, currentGroup) { 
 
    var result = null; 
 

 
    for (e in currentGroup) { 
 
    if (currentGroup[e].intName === groupName) { 
 
     result = currentGroup[e]["Members"]; 
 
    } else if (currentGroup[e]["Members"]) { 
 
     result = deepFindGroup(groupName, currentGroup[e]["Members"]); 
 
    } 
 
    
 
    if (result || result === undefined) break; 
 
    } 
 
    
 
    return result; 
 
} 
 

 
var group = { 
 
    one: { 
 
    intName: 'one', 
 
    Members: { 
 
     one_one: { 
 
     intName: 'one_one', 
 
     } 
 
    } 
 
    }, 
 
    two: { 
 
    intName: 'two', 
 
    Members: { 
 
     two_one: { 
 
     intName: 'two_one', 
 
     Members: {} 
 
     } 
 
    } 
 
    } 
 
} 
 

 
console.log(deepFindGroup('one', group)) // -> {one_one: {intName: 'one_one'}} 
 
console.log(deepFindGroup('one_one', group)) // -> undefined (members are undefined) 
 
console.log(deepFindGroup('two_one', group)) // -> {} 
 
console.log(deepFindGroup('two_two', group)) // -> null

は、覚えておいてください、あなたはundefinedを取得します結果として、undefinedまたはarrayまたはwhateverがメンバーにあることを意味する場合、グループは一致します。nullでない場合見つかりました。

1

あなたの関数は、複数のブランチをしようとしません。一致するものが見つからなくても返します。代わりに、別のブランチを使用して新しい検索を実行できるように、forループを続行する必要があります。

function deepFindGroup(groupName, currentGroup) { 
    var result; 
    console.log("Testing"); 
    for (var e in currentGroup) { 
     if (currentGroup[e].intName == groupName) { 
      console.log(currentGroup[e]["Members"]); 
      return currentGroup[e]["Members"]; 
     } else if (currentGroup[e]["Members"]) { 
      // Don't return before you have looked at the result: 
      result = deepFindGroup(groupName, currentGroup[e]["Members"]); 
      if (result !== undefined) return result; 
     } 
    } 
} 

はまた、あなたの変数が宣言されていることを確認してください:ここで

が見つかりました。値はundefinedそのものになることはありませんと仮定して、あなたがそれを行うことができる方法です。 eを宣言していないので、グローバルであったため、関数スコープの異なる再帰インスタンスが同じe変数を変更し、不規則な動作につながります。

+0

電子メールをありがとう、私は分かりませんでした。これを確認できる正式な情報源はありますか? –

+0

@DominicGrenierこれはかなりよく知られているJSの機能です: 'var'キーワードを使わないと、グローバルスコープで宣言されます。あなたは* oficial *ソースを求めていたので、ここにあります:https://www.ecma-international.org/ecma-262/ –

+0

ECMAScriptのドキュメントよりも公式なものはありません。 https://www.ecma-international.org/ecma-262/#sec-iteration-statements –