JavaScript. Подробное руководство, 6-е издание
Часть 83 из 535 Информация о книге
<b>а = [1,2,3,4, 5];</b><b>a.some(function(x) { return х%2===0; }) // => true: имеются четные числа, </b><b>a.some(isNaN) // => false: нет нечисловых элементов.</b>Обратите внимание, что оба метода,
и<b>every()</b>, прекращают обход элементов массива, как только результат становится известен. Метод<b>some()</b>возвращает<b>some()</b>, как только функция-предикат вернет<b>true</b>, и выполняет обход всех элементов массива, только если функция-предикат всегда возвращает<b>true</b>. Метод<b>false</b>является полной противоположностью: он возвращает<b>every()</b>, как только функция-предикат вернет<b>false</b>, и выполняет обход всех элементов массива, только если функция-предикат всегда возвращает<b>false</b>. Кроме того, отметьте, что в соответствии с правилами математики для пустого массива метод<b>true</b>возвращает true, а метод<b>everу()</b>возвращает<b>some()</b>.<b>false</b>7.9.5. Методы reduce() и reduceRight()
Методы
и<b>reduce()</b>объединяют элементы массива, используя указанную вами функцию, и возвращают единственное значение. Это типичная операция в функциональном программировании, где она известна также под названием «свертка». Примеры ниже помогут понять суть этой операции:<b>reduceRight()</b><b>var а = [1,2,3,4,5]</b><b>var sum = a.reduce(function(x,у) { return х+у }, 0); // Сумма значений</b><b>var product = a.reduce(function(x,у) { return х*у }, 1); // Произвел, значений </b><b>var max = a.reduce(function(x,у) { return (х>у)?х:у; }); // Наибольш. значение</b>Метод
принимает два аргумента. В первом передается функция, которая выполняет операцию свертки. Задача этой функции - объединить некоторым способом или свернуть два значения в одно и вернуть свернутое значение. В примерах выше функции выполняют объединение двух значений, складывая их, умножая и выбирая наибольшее. Во втором (необязательном) аргументе передается начальное значение для функции.<b>reduce()</b>Функции, передаваемые методу
, отличаются от функций, передаваемых методам<b>reduce()</b>и<b>forEach()</b>Знакомые уже значение, индекс и массив передаются им во втором, третьем и четвертом аргументах. А в первом аргументе передается накопленный результат свертки. При первом вызове в первом аргументе функции передается начальное значение, переданное методу reduce() во втором аргументе. Во всех последующих вызовах передается значение, полученное в результате предыдущего вызова функции. В первом примере, из приведенных выше, функция свертки сначала будет вызвана с аргументами 0 и 1. Она сложит эти числа и вернет 1. Затем она будет вызвана с аргументами 1 и 2 и вернет 3. Затем она вычислит 3+3=6, затем 6+4=10 и, наконец, 10+5=15. Это последнее значение 15 будет возвращено методом<b>map().</b><b>reduce().</b>Возможно, вы обратили внимание, что в третьем вызове, в примере выше, методу
передается единственный аргумент: здесь не указано начальное значение. Когда метод<b>reduce()</b>вызывается без начального значения, как в данном случае, в качестве начального значения используется первый элемент массива. Это означает, что при первом вызове функции свертки будут переданы первый и второй элементы массива. В примерах вычисления суммы и произведения точно так же можно было бы опустить аргумент с начальным значением.<b>reduce()</b>Вызов метода
с пустым массивом без начального значения вызывает исключение<b>reduce()</b>. Если вызвать метод с единственным значением - с массивом, содержащим единственный элемент, и без начального значения или с пустым массивом и начальным значением - он просто вернет это единственное значение, не вызывая функцию свертки.<b>ТуреЕrror</b>Метод
действует точно так же, как и метод reduce(), за исключением того, что массив обрабатывается в обратном порядке, от больших индексов к меньшим (справа налево). Это может потребоваться, если операция свертки имеет ассоциативность справа налево, например:<b>reduceRight()</b><b>var а = [2, 3, 4]</b><b>// Вычислить 2^(3^4). Операция возведения в степень имеет ассоциативность справа налево </b><b>var big = a.reduceRight(function(accumulator,value) {</b><b> return Math.pow(value,accumulator);</b><b> });</b>Обратите внимание, что ни
ни<b>reduce(),</b>не принимают необязательный аргумент, определяющий значение<b>reduceRight()</b>внутри функции свертки. Его место занял необязательный аргумент с начальным значением. Если потребуется вызывать функцию свертки как метод конкретного объекта, можно воспользоваться методом<b>this</b>.<b>Function.bind()</b>Следует отметить, что методы
и<b>every()</b>, описанные выше, являются своеобразной разновидностью операции свертки массива. Однако они отличаются от<b>some()</b>тем, что стремятся завершить обход массива как можно раньше и не всегда проверяют значения всех его элементов.<b>reduce()</b>В примерах, представленных до сих пор, для простоты использовались числовые массивы, но методы
и<b>reduce()</b>могут использоваться не только для математических вычислений. Взгляните на функцию<b>reduceRight()</b>в примере 6.2. Она вычисляет «объединение» двух объектов и возвращает новый объект, имеющий свойства обоих. Эта функция принимает два объекта и возвращает другой объект, т. е. она действует как функция свертки, поэтому ее можно использовать с методом<b>union()</b>и обобщить операцию создания объединения произвольного числа объектов:<b>reduce()</b>