почему цикл внутри рекурсивной функции не завершен в javascript

#javascript #function #loops #recursion #tree

#javascript #функция #циклы #рекурсия #дерево

Вопрос:

Мне нужно: проверить каждый узел в дереве, начиная с корня, выполнить цикл на его узле, проверить каждый узел, есть ли какие-либо дочерние элементы, связанные с этим узлом, и снова вызвать ту же функцию (рекурсивная функция). Мой код:


 var tree = new Array();

tree[0] = ["Node1", "Node2", "Node3", "Node4"] 
tree[1] = ["Node1", "Node2"] 
tree[2] = ["Node1", "Node2", "Node4"] 


function schTree(treeArr){
 //LOOP ON CHILD NODE TO CHECK IF THE NODE IS PARANT FOR SOME OTHER NODE OR NOT and do some actions 
     for(i=0;i<treeArr.length; i  ){

                if(treeArr[i].length){
                     schTree(treeArr[i]);
                  };
      }
  }

//call search tree function 
schTree(tree);    
  

Проблема в том :
Цикл не был завершен, если я вспомню функцию.

Я думаю, что при каждом рекурсивном вызове функции она создает новую функцию над текущей функцией (работает в том же месте в памяти, не создавая новую функцию)

Как: Сделать нормальную рекурсивную функцию?????

Заранее спасибо

Магед Раваш

Ответ №1:

Вы получили только первый узел, потому что вы объявили свой цикл for без ключевого слова var

for(i=0;i<treeArr.length; i ) К тому времени, когда был пройден первый массив узлов, я был равен 3

Вот мои комментарии к остальной части вашего кода

 var tree = [];
tree[0] = ["Node1", "Node2", "Node3", "Node4"] 
tree[1] = ["Node5", "Node6"] 
tree[2] = ["Node7", "Node8", "Node9"] 

//recursive function that checks if a node 
function schTree(treeArr){

    //FIX A
    //find out if element is an array
    if(Array.isArray(treeArr)){

    //FIX B
    //You did not declare i with var, meaning each recursive call
    //carried the prior value of i with it.
    //so after iterating over the first node, i = 3
    //which is greater than the length of node 1 and 2
     for(var i=0;i<treeArr.length; i  ){

            //FIX C
            //removed inner length check, not needed
            //schTree checks for array before getting to this
            //point
             schTree(treeArr[i]);
      }
    }
    else {
        //While you'd probably want to do a clause for
        //objects, we'll assume only arrays here.

        //FIX D
        //Do something with the non array element
        console.log(treeArr);
    }
  }
  schTree(tree);
  

Ответ №2:

Способ, которым вы это проверяете, не сработает, потому что буквы имеют .length значение of 1 , поэтому вы получите pass in tree , tree[0] , tree[0][0] , а затем бесконечно переходите, tree[0][0][0] пока стек не станет слишком большим, и вы получите a RangeError . Вместо этого сделайте это:

 function schTree(treeArr){
    for (var i = 0; i < treeArr.length; i  ){
        if (treeArr[i].constructor === String amp;amp; treeArr[i].length > 1) schTree(treeArr[i]);
    }
}
  

Комментарии:

1. Я рассматриваю строку как parant, и каждая буква не оставляет проблем с этим..

2. Хорошо, но вам нужно убедиться, что строка имеет длину больше, чем 1 , чтобы вы не зацикливались на букве.