2016-01-13 3 views
3

Я думаю, d.push(f(b)) никогда не будет выполнен.Рекурсивный вызов функции не выполняется.

Можете ли вы помочь мне понять, что делает этот код? `

function a(f, d) { 
    if (d.length > 0) { 
     var b = d.pop(); 
     a(f, d); 
     d.push(f(b)); 
    } 
} 
+0

'function incr (n) {return n + 1}' и попытаться перейти к '_ar = [[1,2,3,4], 1,2, [3,4,5, 6]] '' a (f, _ar) 'then print' _ar' –

+0

По сути, операция 'map' действительно ужасно. –

+0

в скором времени изменит значение массива, применив функцию обратного вызова на нем. –

ответ

0

Вы можете легко проверить это, скопировав код в консоли, а затем работает a((b) => console.log(b), [1,2,3]), чтобы увидеть, как это работает. Он рекурсивно перебирает массив (мутирует исходный массив) и делает что-то с каждым значением.

4

Это называется рекурсия. Функция, которая вызывает себя до тех пор, пока не будет выполнено какое-либо условие, в этом случае условием является массив a. По существу эта функция принимает функцию f и массив a в качестве параметров. Если массив не пуст, он удаляет последний индекс и снова вызывает себя.

Это продолжается до тех пор, пока массив не будет пуст, а затем каждый рекурсивный вызов вернется и перейдет к следующей строке, которая вызывает функцию, которая была передана вначале, передавая ему значение индекса массива, которое оно выскользнуло, и добавляет возвращаемый результат обратно в массив.

Ниже приведен пример его работы. Push никогда не выполняется до тех пор, пока массив не будет пуст, но до тех пор, пока массив будет иметь больше, чем 0 при первом вызове, в конце концов будет выполняться нажатие. Если массив был пуст, ничего не происходит.

Fiddle: https://jsfiddle.net/3joe4yvz/

function a(f, d) { 
    if (d.length > 0) { 
     var b = d.pop(); 
     a(f, d); 
     d.push(f(b)); 
    } 
} 

var someArray = [1,2,3]; 
function addOne (value) { 
    return value + 1; 
} 
a(addOne,someArray); 
alert(JSON.stringify(someArray)); 
+0

Спасибо за объяснение, upvoted! – bmah

+0

@bmah без проблем !! Удачи! – AtheistP3ace

0

Ваша функция (function a) получает функцию (f) и массив (d) в качестве входных данных.

Скажем, d - это массив, такой как [element1, element2, element3].

Ваша функция pop d элементов одна за другой (вызывая себя рекурсивно) до конечного элемента (element1 в нашем примере).

После того, что он дает элементы функционировать f и оттеснить их в массив d

Таким образом, окончательный результат будет: [f(element1), f(element2), f(element3)]

1

Давайте посмотрим на этот кусок за куском.

function a(f, d) { 
    if (d.length > 0) { // if the list is not empty 
     var b = d.pop(); // remove the last element from the list 
     a(f, d); // call this function recursively with the shortened list 
     d.push(f(b)); // call f with the last item removed 
         // and add it to the list 
    } 
} 

Предположим, у вас есть список с 3-х элементов в нем: [1, 2, 3].

Предположим, что f - это функция, которая удваивает число: function f(x) { return x * 2; }.

Теперь мы будем отслеживать стек вызовов для a(f, [1, 2, 3]).

  1. a(f, [1, 2, 3])
    1. Удалить 3 из списка.
    2. Звонок a(f, [1, 2]).
  2. a(f, [1, 2])
    1. Удалить 2 из списка.
    2. Звонок a(f, [1]).
  3. a(f, [])
    1. Список пуст, ничего не делать.
  4. a(f, [1]) снова
    1. d теперь пуст.
    2. Добавить f(1) в d: d = [2]
  5. a(f, [1, 2]) снова
    1. d теперь [2]
    2. Добавить f(2) в d: d = [2, 4]
  6. a(f, [1, 2, 3]) снова
    1. d теперь [2, 4]
    2. Добавить f(3) в d: d = [2, 4, 6]
  7. Окончательный результат: d = [2, 4, 6]

В некотором смысле, это реализация map.

+0

Отличное объяснение, я получил суть этого, но я все еще чувствую, что на шаге 3. a (f, []) d.length> 0 будет ложным, и поэтому ничего в последующем {} не должно выполняться, тогда как d .push .. выполняется ??? Если бы это не было за пределами инструкции if, чтобы работать так, как вы сказали. – bmah

+0

@bmah Помните, что это рекурсивная функция. После возвращения функции возвращается к той точке, в которой она была вызвана. Это не значит, что 'a (f, [])' выполняет изменения, это значит, что все остальные вызовы 'a' выполняют их' d.push (f (b)) ', когда он возвращается в свою очередь. Для рекурсии есть немного шутки об изучении этого: чтобы понять рекурсию, вы должны сначала понять рекурсию. –

0

Это рекурсивная реализация map, или array_map. Он изменяет исходный массив (как если бы он был передан ссылкой/указателем), применяя первый параметр (f, функция) к каждому из элементов в списке (d).

function a(f, d) { 
    if (d.length > 0) { 
     var b = d.pop(); 
     a(f, d); 
     d.push(f(b)); 
    } 
} 

function my_array_map(my_func, my_list) { 
    if (my_list.length > 0) { 
     var first_element = my_list.pop(); 
     my_array_map(my_func, my_list); 
     my_list.push(my_func(first_element)); 
    } 
} 

var the_list = [2, 4, 6, 8]; 
var multiply = function(val) { 
    return val * 2; 
}; 
var divide = function(val) { 
    return val/2; 
} 


my_array_map(multiply, the_list); 
console.log(the_list); // [4, 8, 12, 16]                    
my_array_map(divide, the_list); 
console.log(the_list); // [2, 4, 6, 8] 
Смежные вопросы