Функции высшего порядка - Javascript

Я работаю через Eloquent Javascript. Функцияподсчитывать принимает массив и тестовую функцию (равен (х)) в качестве аргументов и возвращает количество элементов в массиве, для которого тестовая функция вернула значение true.

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

Может ли кто-нибудь помочь мне увидеть, откуда конкретно берется ценность для общего количества? Я хочу иметь более ясную картину в моей голове.

function count(test, array) {
  return reduce(function(total, element) { // Where is the value for total coming from?
    return total + (test(element) ? 1 : 0);
  }, 0, array);
}

function equals(x) {
  return function(element) {return x === element;};
}

function countZeroes(array) {
  return count(equals(0), array);
}

Уменьшить функцию от ранее:

function reduce(combine, base, array) {
  forEach(array, function (element) {
    base = combine(base, element);
  });
  return base;
}

Функция forEach от ранее:

function forEach(array, action) {
  for (var i = 0; i < array.length; i++)
    action(array[i]);
}
 phant0m03 нояб. 2012 г., 21:39
(надеясь, что это вызовет приглашение в чат) редактировать: пока нет, может быть, я смогу создать комнату, все еще пишу свой ответ, потерпите меня
 phant0m03 нояб. 2012 г., 21:19
Казалось бы, да, в противном случае вы бы неКонечно, не стоит задавать этот вопрос: P Я думаю, что было бы лучше, если бы вы описали свою точку зрения о том, как функции взаимодействуют в первую очередь, прежде чем мы продолжим отвечать на этот вопрос.
 KMcA03 нояб. 2012 г., 21:04
Да, логически я это вижу. Я'м просто не ясно, откуда конкретно берется значение.
 Asad Saeeduddin03 нояб. 2012 г., 21:04
base передается какtotal аргумент, насколько я могу судить.base здесь 0, такtotal 0 в этой оценке.
 Asad Saeeduddin03 нояб. 2012 г., 21:43
@AMK Первый - это вызов функции. Вторая функцияопределение.
 KMcA03 нояб. 2012 г., 21:44
Асад, но они эквивалентны правильно?
 KMcA03 нояб. 2012 г., 21:17
Да, я вытащил все со вчерашнего дня снова этим утром, и это было довольно ясно. Это был следующий код после него. Я предполагаю, что я'Я просто пытаюсь увидеть, как работают линии при использовании функций в качестве параметров.
 KMcA03 нояб. 2012 г., 22:31
 phant0m03 нояб. 2012 г., 22:03
Я нене понимаю, что вы подразумеваете под планом.
 Asad Saeeduddin03 нояб. 2012 г., 21:27
@ phant0m Ух ты, ASCII художественное объяснение ftw. АМК не могли бы вы объяснить, где именно у вас возникают трудности с объяснением? Бьюсь об заклад, это также поможет, если вы используете Firebug или что-то подобное, чтобы пройти через код.
 KMcA03 нояб. 2012 г., 21:25
phant0m, я вижу, что Reduce передается анонимной функции, а не функции объединения. И внутри анонимной функции вы используете функцию equals (x). Я просто могуобернуть голову вокруг точной команды, которая является основой для "Всего" значение.
 KMcA03 нояб. 2012 г., 22:08
Какова точная команда, которую вы читаете, которая говорит вам, что 0 является значением суммы? Я знаю, что общее число === base === 0, но где строка, которая конкретно подразумевает это.
 KMcA03 нояб. 2012 г., 21:39
так эти два вызова функций по существу равны между собой: объединить (база, элемент) и функцию (всего, элемент)?
 phant0m03 нояб. 2012 г., 22:12
Внутри:count()reduce(function {...}, 0, array, Видишь этот ноль там? Это передаетсяreduce и там известен какbase, что делает для начального значенияtotal на первой итерации внутри.forEach
 phant0m03 нояб. 2012 г., 22:27
;) Я имею "развернутая» последняя функция вызывает в моем ответе, так что вы можете видеть, к чему сводится код. Попытка понять все сразу является добродетельной, но может быть лучше попытаться понятьreduce вначале само собой. Снижение (слева) всегда делает следующее:(...((((a + x1) + x2) + x3) + x4) + ...) + xlast, но+ не обязательно математическая функция плюс, но любая функция, которая принимает два аргумента и возвращает один и тот же тип.a обозначает начальный элемент. Например, если вы хотите сложить список чисел, вы можете использовать:reduce(plus, 0, numbers)
 KMcA03 нояб. 2012 г., 21:34
Я довольно новичок в этом сайте и разработке в целом. Если это будет проще, мы можем общаться, а не писать?
 KMcA03 нояб. 2012 г., 21:43
Я думаю, что мне нравится делать (яя пытаюсь научить себя), это сравнить мой план функции с функцией, которая выполняет значения. Чтобы'Это то, что я пытался сделать здесь.
 Asad Saeeduddin03 нояб. 2012 г., 21:51
@AMK посмотреть, поможет ли мое обновление.
 KMcA03 нояб. 2012 г., 22:02
Я действительно ценю всю помощь, но то, что яЯ пытаюсь понять, что это за функция (всего, элемент)?
 KMcA03 нояб. 2012 г., 22:20
Да, я вижу 0 в качестве базового аргумента в Reduce. Я просто буду продолжать смотреть на это, я думаю.
 Asad Saeeduddin03 нояб. 2012 г., 21:32
@ phant0m Ах, хорошо. Кажется, проблема в том, что у АМК возникают проблемы с пониманием названияcombine который используется для анонимной функции внутри redu.I '
 phant0m03 нояб. 2012 г., 21:13
Похоже, это практически так же, как вашпоследний вопрос, Каковы отличия здесь от вашего последнего вопроса?

Ответы на вопрос(2)

Решение Вопроса

3 аргумента, которые вы передали, чтобы уменьшить:

{
    combine:function(total, element){...},
    base:0,
    array:array
}

Затем функция принимаетbase и передает егоcombine функционировать какtotal аргумент:

base = combine(base, element);

По сути, здесь происходит то, что для каждого элемента в массиве, который вы только что передали (как третий аргументarray) функция принимает аргументbase и увеличивает его, используя предоставленную вами анонимную функцию (которая сначала проверяет, прошел ли элементtest). Наконец, после того, как он прошел по всем элементам, он возвращает окончательное значение.base

Возможно, это поможет объяснить:

function count(test, testarray) {
  var anon = function(total, element) { // Where is the value for total coming from?
    return total + (test(element) ? 1 : 0);
  };
  //now anon is a function.
  return reduce(anon, 0, testarray);
}

Давайте посмотрим на вызов и определение функции внимательно:

return   reduce(anon   , 0   , testarray);
                  |      |     |
                  v      v     v
function reduce(combine, base, array) {
    combine;    //the function that is passed in as the first argument
    base;       //the number that is passed in as the second argument
    array;      //the array that is passed in as the third argument

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

 KMcA03 нояб. 2012 г., 21:10
Это то, что я предположил. Спасибо за проверку.

Я вижу, что редукция передается анонимной функции, а не функции объединения

Это не совсем так. Анонимная функцияявляется combine функция.

combine(base, element) противfunction(total, element)

эти два вызова функций по существу равны друг другу: объединить (база, элемент) и функцию (всего, элемент)?

Нет они'это совершенно разные вещи.

Первый вызов функции, на функцию, на которую ссылается.combine

Второе, однако, оценивает новое значение функции. В случае:

reduce(function(total, element) {...}, ...);

reduce() передается значение функции, что это означает, чтоновая функция являетсясозданныйфункция, которая принимает два параметра (обозначается какtotal а такжеelement). Эта функция затем передается.reduce

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

                   return value of reduce()
                   /
                 etc ...
                /
            combine    
           /       \
       combine      xs[2]
      /       \
  combine      xs[1]
 /       \
0         xs[0]

Конечно, это только показываеткакие бывает, а некак и я думаю, что в вашем случае выпросяткак, Просто запомните эту визуализацию, чтобы увидеть, что получится в результате.

Подставляющие функции

Чтобы было яснее, что происходит, яЯ собираюсь постепенно заменить функции, которые передаются.

Старт программы:

function countZeroes(array) {
  return count(equals(0), array);
}

equals(0) (Вы можете назвать это формой карри) оценивает функцию, которая передается.count()

Это приводит в основном к следующемуcount() функция:

function count(array) {
  return reduce(function(total, element) { // Where is the value for total coming from?
    return total + (0 == element ? 1 : 0);
  }, 0, array);
}

Отсюда мы можем извлечьcombine аргумент:

function combine(total, element) { // Where is the value for total coming from?
    return total + (0 == element ? 1 : 0);
}

Это функция, которая используется в функции Reduce:

function reduce(base = 0, array) {
  forEach(array, function (element) {
    base = combine(base, element);
  });
  return base;
}

reduce(0, array) называется изcount() функция. Функция, которая передаетсяforEach теперь можно переписать так, принимая во внимание реализацию:combine

function reduce(base = 0, array) {
  forEach(array, function (element) {
    base = base + (0 == element ? 1 : 0);
  });
  return base;
}

Имейте в виду, чтоbase представляет наш.total

В качестве нашего последнего шага мы принимаем во внимание то, чтоforEach() делает.

function reduce(base = 0, array) {
  for (var i = 0; i < array.length; i++)
    base = base + (0 == array[i] ? 1 : 0);
  }
  return base;
}

Так вот чтоcount() по сути выглядит так, все вызовы развернуты:

function count(array) {
  var base = 0;
  for (var i = 0; i < array.length; i++)
    base = base + (0 == array[i] ? 1 : 0);
  }
  return base;
}

Ваш ответ на вопрос