[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]
[9, 0]
[9, NaN]
[9, undefined]
reduce
from a purely practical point of view.reduce
(from an academic point of view).reduce
.reduce
(hereinafter we mean Array.prototype.reduce
), along with other functions from the Array
prototype: filter
, map
, forEach
, some
, every
, is a higher order function, that is, it accepts another function as input (we will call this transmitted f*
) function. The f*
function will be called with some arguments for each element of the collection.reduce
, used to generate some aggregate value based on the collection. It consistently applies f*
to each element, passing it the current value of the variable in which the result (of the accumulator) and the current element being accumulated are accumulated. Also, in reduce
you can pass the initial value of the battery. Moreover, (!) The behavior of reduce
will differ depending on whether this value is passed or not .Math.pow
produces exponentiation, that is, its behavior varies depending on the degree transferred : it can be a square, a cube, or a square root, or any other real degree.reduce
behave if called on an empty array?Math.pow
behave if the degree is not Math.pow
?null
values: null
, undefined
, NaN
, and others will work permissively: they will try to do something even with not quite correct data.TypeError
that is responsible for the second subexpression. The reduce
function on an empty array And without a passed initial value throws a TypeError
.reduce
specificationinitialValue
passed, then at the first iteration the function will be called with this value and the value of the first element of the array. If, however, initialValue
not passed, then the function will be called with the values ​​of the first and second elements of the array. It also follows that if the initial value is not passed, the function is called at one time less , otherwise it is exactly as many times as there are elements in the array.initialValue
like this: array.reduce(fn, initialValue) ⇔ [ initialValue ].concat(array).reduce(fn);
f*
ignored . If the array is empty and the initial value is not passed, then TypeError
thrown. [].reduce(fn, initialValue) ⇔ [ initialValue ].reduce(fn) ⇒ initialValue; [].reduce(fn) ⇒ TypeError;
f*
with values ​​from the input data. If the initial value is passed, then it is the data element that precedes the first element. If nothing is transmitted (there are no elements and no initial value), then the function has no data to generate the aggregate, and it throws an exception. Anyway, the behavior is a bit complicated and can become a pitfall. reduce
, in fact, is overloaded for one argument and for two, and overloaded options have different behavior on an empty array.reduce
and Math.pow
.reduce
reduce
is remarkable in that it can be used to describe all other higher-order functions of an Array
object: forEach
, filter
, map
, some
, every
.reduce
must accumulate a value of the same type as the values ​​in the array. Indeed, it seems logical to think that if we take an array of numbers and sum them, we also get a number. If we take an array of strings and concatenate them, we also get a string. This is natural, but reduce
also capable of returning arrays and objects. Moreover, the transfer will occur from iteration to iteration due to the battery. This allows you to build on reduce
functions of any complexity.map
: function map$viaReduce (array, fn) { return array.reduce(function (memo, item, index, array) { return memo.concat([ fn(item, index, array) ]); }, []); };
fn
. Also not forgotten here, fn
accepts not only an element, but an index and an array with subsequent parameters. The parameter of the function concat
wrapped in an array to avoid “unwinding” the value if fn
returns an array. An empty array is passed as the initial value.filter
functions as an exercise, and one of the quantifier functions: some
or every
. You will notice that the return of the accumulated array is used everywhere.uniq
function. As you know, JavaScript suffers from the lack of many necessary things in the standard lib. In particular, there is no function that eliminates duplicates in the array, and developers use different custom implementations (I personally advise using _.uniq
from LoDash / Underscore).reduce
capabilities, it will come down. function uniq$viaReduce (array) { return array.reduce(function (memo, item) { return (~ memo.indexOf(item) ? null : memo.push(item)), memo; }, []); };
-1
. The whole expression is wrapped in a comma operator, which at each step (after all actions) returns a memo
. It is noteworthy that this implementation also maintains order in the array.reduce
and indexOf
will have a negative effect on the performance of such uniq
, and the abundant use of one-liners and tildes will affect readability.zipObject
function zipObject
essence in that it takes as an input an array of pairs (arrays), where the zero element is the key and the first is the value, and returns the constructed Object
with the corresponding keys / values. npm install StreetStrider/habrahabr-javascript-reduce
src/
are examples of functions, in tests/
- jasmine-tests. You can run all the tests using npm test
.Math.pow
in the absence of a degree (and other boundary cases).reduce
reduce
has reduceRight
. It is needed to aggregate arrays from right to left, without the need for costly reverse
._.reduce
, _.reduceRight
. They have a number of additional features.reduce
. Yes. But it is not officially recommended for use and it has even been removed from global namespace. Instead, it is proposed to use list expressions and for-in
constructions. The code turns out more, but it becomes much more readable. This corresponds to the Tao language.reduce/reduceRight
is called foldl/foldr
.COUNT
, SUM
, AVG
, MAX
, MIN
. These functions are used to reduce the resulting sample to a single tuple. Similar functions can be implemented in JavaScript (also on reduce
).COUNT
) return NULL
if the sample is empty ( COUNT
returns a specific value: 0
). This is completely analogous to the JS TypeError
on an empty list. postgres=# SELECT SUM(x) FROM (VALUES (1), (2), (3)) AS R(x); sum ----- 6 (1 row)
postgres=# SELECT SUM(x) IS NULL AS sum FROM (VALUES (1), (2), (3)) AS R(x) WHERE FALSE; sum ----- t (1 row)
reduce
is a powerful function in terms of which other higher order functions can be expressed, such as map
and filter
. With this power, complexity comes to reduce
. reduce
can be successfully used for various summations and groupings, however, it is worth remembering that any aggregation can be rewritten using a regular loop, which can be easier to read.reduce
can return anything.Source: https://habr.com/ru/post/222317/
All Articles