2015-12-17 3 views
3

Мне нужно найти узел по id в дереве. Для этого я спускаюсь с помощью двух вложенных циклов. Но вернулся неопределенный.Возвращает значение из цикла в рекурсивной функции

function searchInTreeById(node, matchingId) { 
    var res; 
    if (node.select('id').get() == matchingId) { 
     res = node.get(); 
     return res 
    } else { 
     if (node.exists('childObjects')) { 
      node.select('childObjects').map(function (cursor, i) { 
       cursor.select('children').map(function (cursorChild, j) { 

        if (cursorChild.select('id').get() === matchingId) { 
         // console.log(cursorChild.get()) //this console.log is execute 
         res = cursorChild.get(); 
         return res; 
        } else { 
         // console.log(cursorChild.get()) 
         searchInTreeById(cursorChild, matchingId) 
        } 
       }) 
      }) 
     } else { 
      res = node; 
     } 
    } 
    return res 
} 
+0

Игнорирование результата 'searchInTreeById' выглядят очень подозрения (не уверен, что«баобаб»есть, так что, возможно, это нормально, что бы это ни было) –

+0

@AlexeiLevenkov если я установить Рез = searchInTreeById (cursorChild, matchId), то func возвращает последний посещенный узел ... –

+2

Боковое примечание: 'map' обычно является неправильным способом для выполнения поиска - скорее всего, есть другая функция (аналогичная' Array.find'), которая позволяет остановить итерацию в средний. –

ответ

3

Когда совпадение не сразу найдено, вы вызываете рекурсивно функцию, которая должна в конечном итоге вернуть результат. Но это не так.

searchInTreeById(cursorChild, matchingId); 

Однако, используя карту применит чек/функции для каждого ребенка, но результат теряется в любом случае, в этом случае. Функция map применяет функцию, заданную параметрами к элементам массива, и возвращает новое значение для каждого элемента - новый массив. В зависимости от того, как быстро элемент найден, копия дерева встроена в память (традиционная рекурсивная функция сохраняет только путь элементов до узла).

Таким образом, можно присвоить результат карты в массив, каждый элемент которой устанавливается в нуль если этот конкретный ребенок не имел спичку, или узла если найдено. Затем вы проверяете все элементы этого созданного массива и возвращаете нуль или узел, если он найден (тогда вызывающий заполняет массив на этом уровне и т. Д.).

Вы также можете использовать глобальную переменную

var found = null; 

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

Но возможно карте можно было бы избежать вместе?

Вместо того, чтобы использовать карту, собрать детей в массиве и перебрать этот массив, вызывать рекурсивно функцию и немедленно возвращать соответствие узла.

Предложенного код (не тестировался)

function searchInTreeById(node, matchingId) { 
    if (node.select('id').get() == matchingId) { 
     return node.get(); 
    } 
    if (node.exists('childObjects')) { 
     var list = node.select('childObjects'); 
     for(var i=0 ; i<list.length ; i++) { 
      var res = searchInTreeById(list[i], matchingId); 
      if (res) return res; 
     } 
    } 
    return null; 
} 

Отказ от ответственности: баобаба первого таймера. (Я прочитал this хотя)

+0

большое спасибо !!!! Я немного изменил этот код, и это работает так, как это было! –

+0

Итак, что вы изменили, используйте глобальный var? получить результат карты в массиве? Итерации над детьми? –

+0

пересказать по-детски и сменить детали, связанные с baobab? например: var list = parentNode.select ('childObjects'). get(); –

Смежные вопросы