web-dev-qa-db-ja.com

再帰関数のループから抜け出すにはどうすればよいですか?

子カテゴリオブジェクトの配列を持つことができるカテゴリオブジェクトの配列を使用しています。トリッキーな部分は、このネストされたデータの深さが不明である(そして変更される可能性がある)ことです。 (下のサンプルを参照してください。)私がやろうとしているのは、カテゴリオブジェクトに「トレイル」を返すことですが、さまざまな問題が発生しています。

理想的には、findCategory('b4')のようなものは次を返します:['c1', 'd2', 'd3', 'b4'](サンプルを参照)。

私の問題は、再帰によってネストされたループから適切に抜け出すのに問題があることだと思います。トレイルに余分なカテゴリが含まれることがあります。または、問題が発生したと思うと、より深いネストされたカテゴリがトレイルに表示されます。

1つの結果は次のようになります。明らかに、b4でループを強制終了しているわけではなく、結果が2回検出される理由がわかりません。

b4
FOUND
["c1", "d2", "d3", "b4"]
e2
FOUND
["c1", "d2", "d3", "b4", "e2"] 

Underscore.jsバージョンも表示できる場合はボーナス。

JSFiddleリンク ここ...

// Start function
function findCategory(categoryName) {
    var trail = [];
    var found = false;

    function recurse(categoryAry) {

        for (var i=0; i < categoryAry.length; i++) {
            console.log(categoryAry[i].category);
            trail.Push(categoryAry[i].category);

            // Found the category!
            if ((categoryAry[i].category === categoryName) || found) {
                console.log('FOUND');
                found = true;
                console.log(trail);
                break;

            // Did not match...
            } else {

                // Are there children / sub-categories? YES
                if (categoryAry[i].children.length > 0) {

                    console.log('recurse');
                    recurse(categoryAry[i].children);

                // NO
                } else {
                    trail.pop();
                    if (i === categoryAry.length - 1) {
                        trail.pop();
                    }
                }
            }

        } 
    }

    return recurse(catalog);
}

console.clear();
console.log(findCategory('b4'));

例えば。カテゴリオブジェクトのネストされた配列を持つ配列カテゴリオブジェクト。入れ子の深さが不明であると仮定します。

var catalog = [
{
    category:"a1",
    children:[
        {
            category:"a2",
            children:[]
        },
        {
            category:"b2",
            children:[
                {
                    category:"a3",
                    children:[]
                },
                {
                    category:"b3",
                    children:[]
                }
            ]
        },
        {
            category:"c2",
            children:[]
        }
    ]
},
{
    category:"b1",
    children:[]
},
{
    category:"c1",
    children:[
        {
            category:"d2",
            children:[
                {
                    category:"c3",
                    children:[]
                },
                {
                    category:"d3",
                    children:[
                        {
                            category:"a4",
                            children:[]
                        },
                        {
                            category:"b4",
                            children:[]
                        },
                        {
                            category:"c4",
                            children:[]
                        },
                        {
                            category:"d4",
                            children:[]
                        }
                    ]
                }
            ]
        },
        {
            category:"e2",
            children:[
                {
                    category:"e3",
                    children:[]
                }
            ]
        }
    ]
}
];
11
jmk2142

試してみてください

function findCategory(categoryName) {
    var trail = [];
    var found = false;

    function recurse(categoryAry) {

        for (var i = 0; i < categoryAry.length; i++) {
            trail.Push(categoryAry[i].category);

            // Found the category!
            if ((categoryAry[i].category === categoryName)) {
                found = true;
                break;

                // Did not match...
            } else {
                // Are there children / sub-categories? YES
                if (categoryAry[i].children.length > 0) {
                    recurse(categoryAry[i].children);
                    if(found){
                        break;
                    }
                }
            }
            trail.pop();
        }
    }

    recurse(catalog);

    return trail
}

デモ: フィドル

21
Arun P Johny

return stmtは機能しますが、ループがほどけるたびに呼び出されることを覚えておいてください。これはあなたが見ているものではありません。例

// global scope
String matchingVariable;

int getMatch(index count, String input, String[] inputs){

  if(isValid(input) || count < inputs.length){
    // your condition is met and break
    // assign your value to global scope variable 
    matchingVariable = input;
  }else if(matchingVariable ==null){
     ++count
     if(count < inputs.length){
       getMatch(count, input+inputs[count], inputs)
     }

    // NOTE RETURN - I WOULDN'T DO THIS
    return input;  

   // doesn't work instead assign the input to global scope variable when a match is found.
  }

}
0
Anand Kishore