Выразительный JavaScript (Хавербеке) - страница 51

>    if (test(array[i]))

>      passed.push(array[i]);

>  }

>  return passed;

>}


>console.log(filter(ancestry, function(person) {

>  return person.born > 1900 && person.born < 1925;

>}));

>// → [{name: "Philibert Haverbeke", …}, …]

Используется аргумент с именем >test – это функция, которая производит вычисления проверки. Она вызывается для каждого элемента, а возвращаемое ею значение определяет, попадает ли этот элемент в возвращаемый массив.

В файле оказалось три человека, которые были молоды в 1924 – дедушка, бабушка и двоюродная бабушка.

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

Как и >forEach, >filter – это один из стандартных методов массива. В примере мы описали такую функцию, только чтобы показать, что она делает внутри. Отныне мы будем использовать её просто:

>console.log(ancestry.filter(function(person) {

>  return person.father == "Carel Haverbeke";

>}));

>// → [{name: "Carolus Haverbeke", …}]

Преобразования при помощи map

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

Метод >map преобразовывает массив, применяя функцию ко всем его элементам и строя новый массив из возвращаемых значений. У нового массива будет та же длина, что у входного, но его содержимое будет преобразовано в новый формат.

>function map(array, transform) {

>  var mapped = [];

>  for (var i = 0; i < array.length; i++)

>    mapped.push(transform(array[i]));

>  return mapped;

>}


>var overNinety = ancestry.filter(function(person) {

>  return person.died - person.born > 90;

>});

>console.log(map(overNinety, function(person) {

>  return person.name;

>}));

>// → ["Clara Aernoudts", "Emile Haverbeke",

>//    "Maria Haverbeke"]

Что интересно, люди, которые прожили хотя бы до 90 лет – это те самые, что мы видели ранее, которые были молоды в 1920-х годах. Это как раз самое новое поколение в моих записях. Видимо, медицина серьёзно улучшилась.

Как и >forEach и >filter, >map также является стандартным методом у массивов.

Суммирование при помощи reduce

Другой популярный пример работы с массивами – получение одиночного значения на основе данных в массиве. Один пример – уже знакомое нам суммирование списка номеров. Другой – поиск человека, родившегося раньше всех.

Операция высшего порядка такого типа называется >reduce (уменьшение; или иногда >fold, свёртывание). Можно представить её в виде складывания массива, по одному элементу за раз. При суммировании чисел мы начинали с нуля, и для каждого элемента комбинировали его с текущей суммой при помощи сложения.