Baseline Widely available
reduce()
æ¹æ³å°ä¸åç´¯å å¨åé£å䏿¯é
å
ç´ ï¼ç±å·¦è³å³ï¼å³å
¥åå¼å½å¼ï¼å°é£ååçºå®ä¸å¼ã
const array1 = [1, 2, 3, 4];
// 0 + 1 + 2 + 3 + 4
const initialValue = 0;
const sumWithInitial = array1.reduce(
(accumulator, currentValue) => accumulator + currentValue,
initialValue,
);
console.log(sumWithInitial);
// Expected output: 10
èªæ³
arr.reduce(callback[accumulator, currentValue, currentIndex, array], initialValue)
忏
callback
: ç¨æ¼èçé£å䏿¯åå ç´ çå½å¼ï¼å¯å³å ¥åå忏ï¼
accumulator
ç¨ä¾ç´¯ç©åå¼å½å¼åå³å¼çç´¯å å¨ï¼accumulatorï¼æ initialValue
ï¼è¥ææä¾ç話ï¼è©³å¦ä¸æï¼ãç´¯å 卿¯ä¸ä¸æ¬¡å¼å«å¾ï¼æåå³çç´¯å æ¸å¼ã
currentValue
åé£åç®åæè¿ä»£èçä¸çå ç´ ã
currentIndex
鏿æ§
åé£åç®åæè¿ä»£èçä¸çå
ç´ ä¹ç´¢å¼ãè¥æå³å
¥ initialValue
ï¼åç±ç´¢å¼ 0 ä¹å
ç´ éå§ï¼è¥ç¡åèªç´¢å¼ 1 ä¹å
ç´ éå§ã
array
鏿æ§
å¼å« reduce()
æ¹æ³çé£åã
initialValue
鏿æ§
callback
æè¦å³å
¥çç´¯å å¨åå§å¼ãè¥æ²ææä¾åå§å¼ï¼ååé£åç第ä¸åå
ç´ å°æè¢«ç¶ä½åå§çç´¯å å¨ãå妿¼ä¸å空é£åå¼å« reduce()
æ¹æ³ä¸æ²ææä¾ç´¯å å¨åå§å¼ï¼å°æç¼çé¯èª¤ãç°¡åå¾ççµæå¼ã
æè¿°reduce()
æå°æ¯ä¸åç®åè¿ä»£å°çé£åå
ç´ ï¼é¤äºç©ºå¼ä»¥å¤ï¼å·è¡ callback
å½å¼ï¼åå¼å½å¼ææ¥æ¶åå忏ï¼
accumulator
currentValue
currentIndex
array
ç¶åå¼å½å¼ç¬¬ä¸æ¬¡è¢«å¼å«æï¼accumulator
è currentValue
çå¼å¯è½çºå
©ç¨®ä¸åççæ³ï¼è¥å¨å¼å« reduce()
æææä¾ initialValue
ï¼å accumulator
å°æçæ¼ initialValue
ï¼ä¸ currentValue
æçæ¼é£åä¸ç第ä¸åå
ç´ å¼ï¼è¥æ²ææä¾ initialValue
ï¼å accumulator
æçæ¼é£åç第ä¸åå
ç´ å¼ï¼ä¸ currentValue
å°æçæ¼é£åç第äºåå
ç´ å¼ã
åè¨»ï¼ åå¦ initialValue
æªè¢«æä¾ï¼reduce()
å°æè·³é第ä¸åé£åç´¢å¼ï¼å¾é£åç´¢å¼ 1 éå§å·è¡åå¼å½å¼ãè¥ææä¾ initialValue
ï¼åæç±é£åç´¢å¼ 0 éå§å·è¡ã
è¥é£åçºç©ºä¸æ²ææä¾ initialValue
ï¼å°ææåº TypeError
ãåå¦é£ååªæä¸åå
ç´ ï¼ç¡è«å
¶ç´¢å¼ä½ç½®çºä½ï¼ä¸¦ä¸æ²ææä¾ initialValue
ï¼æå¦ææä¾äº initialValue
ä½é£åçºç©ºï¼åæ¤å¯ä¸çå¼å°æè¢«ç´æ¥åå³è䏿å¼å« callback
å½å¼ã
æä¾ç´¯å å¨åå§å¼é常è¼çºå®å
¨ï¼å çºå¨æ²æå³å
¥ initialValue
çæ
æ³ä¸ææä¸ç¨®å¯è½ç輸åºçµæï¼å¦ä¸åç¯ä¾ï¼
var maxCallback = (acc, cur) => Math.max(acc.x, cur.x);
var maxCallback2 = (max, cur) => Math.max(max, cur);
// reduce() without initialValue
[{ x: 22 }, { x: 42 }].reduce(maxCallback); // 42
[{ x: 22 }].reduce(maxCallback); // { x: 22 }
[].reduce(maxCallback); // TypeError
// map/reduce; better solution, also works for empty or larger arrays
[{ x: 22 }, { x: 42 }].map((el) => el.x).reduce(maxCallback2, -Infinity);
reduce() å¦ä½éä½
åè¨ reduce()
以ä¸ä¾æ¹å¼ä½¿ç¨ï¼
[0, 1, 2, 3, 4].reduce(
function (accumulator, currentValue, currentIndex, array) {
return accumulator + currentValue;
},
);
æå³å ¥çåå¼å½å¼å°è¢«å¼å«åæ¬¡ï¼æå³å ¥ç忏èåå³å¼å¦ä¸æç¤ºï¼
callback
accumulator
currentValue
currentIndex
array
return value first call 0
1
1
[0, 1, 2, 3, 4]
1
second call 1
2
2
[0, 1, 2, 3, 4]
3
third call 3
3
3
[0, 1, 2, 3, 4]
6
fourth call 6
4
4
[0, 1, 2, 3, 4]
10
reduce()
çæçµåå³å¼å°ææ¯æå¾ä¸æ¬¡å¼å«åå¼å½å¼çåå³å¼ (10
)ã
ä½ ä¹å¯ä»¥å³å ¥ä¸åç®é å½å¼ä¾æ¿ä»£ä¸å宿´çå½å¼ã䏿¹çç¨å¼ç¢¼å·è¡ççµæå°èåè¿°ä¾åç¸åã
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr);
å¦æä½ ææä¾ç¬¬äºå忏å¼çµ¦ reduce()
ï¼å·è¡ççµæå¦ä¸ï¼
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue;
}, 10);
callback
accumulator
currentValue
currentIndex
array
return value first call 10
0
0
[0, 1, 2, 3, 4]
10
second call 10
1
1
[0, 1, 2, 3, 4]
11
third call 11
2
2
[0, 1, 2, 3, 4]
13
fourth call 13
3
3
[0, 1, 2, 3, 4]
16
fifth call 16
4
4
[0, 1, 2, 3, 4]
20
reduce()
å·è¡ççµæå°ææ¯ 20
ã
var sum = [0, 1, 2, 3].reduce(function (a, b) {
return a + b;
}, 0);
// sum is 6
å¦å¤ï¼ä¹å¯ä»¥å¯«æç®é å½å¼ï¼
var total = [0, 1, 2, 3].reduce((acc, cur) => acc + cur, 0);
æ¤å¹³ä¸åå¤ç¶é£å
var flattened = [
[0, 1],
[2, 3],
[4, 5],
].reduce(function (a, b) {
return a.concat(b);
}, []);
// flattened is [0, 1, 2, 3, 4, 5]
å¦å¤ï¼ä¹å¯ä»¥å¯«æç®é å½å¼ï¼
var flattened = [
[0, 1],
[2, 3],
[4, 5],
].reduce((acc, cur) => acc.concat(cur), []);
è¨ç®ç¸åå
ç´ æ¸é並以ç©ä»¶éµå¼é¡¯ç¤º
var names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
var countedNames = names.reduce(function (allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
// countedNames is:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
ä½¿ç¨ spread éç®åè給å®åå§å¼ï¼çµåç©ä»¶ä¸çé£åå
ç´
// friends - an array of objects
// where object field "books" - list of favorite books
var friends = [
{
name: "Anna",
books: ["Bible", "Harry Potter"],
age: 21,
},
{
name: "Bob",
books: ["War and peace", "Romeo and Juliet"],
age: 26,
},
{
name: "Alice",
books: ["The Lord of the Rings", "The Shining"],
age: 18,
},
];
// allbooks - list which will contain all friends' books +
// additional list contained in initialValue
var allbooks = friends.reduce(
function (prev, curr) {
return [...prev, ...curr.books];
},
["Alphabet"],
);
// allbooks = [
// 'Alphabet', 'Bible', 'Harry Potter', 'War and peace',
// 'Romeo and Juliet', 'The Lord of the Rings',
// 'The Shining'
// ]
ç§»é¤é£åä¸çéè¤é
ç®
let arr = [1, 2, 1, 2, 3, 5, 4, 5, 3, 4, 4, 4, 4];
let result = arr.sort().reduce((init, current) => {
if (init.length === 0 || init[init.length - 1] !== current) {
init.push(current);
}
return init;
}, []);
console.log(result); //[1,2,3,4,5]
åºåå·è¡ Promise
/**
* Runs promises from promise array in chained manner
*
* @param {array} arr - promise arr
* @return {Object} promise object
*/
function runPromiseInSequense(arr) {
return arr.reduce((promiseChain, currentPromise) => {
return promiseChain.then((chainedResult) => {
return currentPromise(chainedResult).then((res) => res);
});
}, Promise.resolve());
}
// promise function 1
function p1() {
return new Promise((resolve, reject) => {
resolve(5);
});
}
// promise function 2
function p2(a) {
return new Promise((resolve, reject) => {
resolve(a * 2);
});
}
// promise function 3
function p3(a) {
return new Promise((resolve, reject) => {
resolve(a * 3);
});
}
const promiseArr = [p1, p2, p3];
runPromiseInSequense(promiseArr).then((res) => {
console.log(res); // 30
});
Polyfill
// Production steps of ECMA-262, Edition 5, 15.4.4.21
// Reference: http://es5.github.io/#x15.4.4.21
// https://tc39.github.io/ecma262/#sec-array.prototype.reduce
if (!Array.prototype.reduce) {
Object.defineProperty(Array.prototype, "reduce", {
value: function (callback /*, initialValue*/) {
if (this === null) {
throw new TypeError(
"Array.prototype.reduce " + "called on null or undefined",
);
}
if (typeof callback !== "function") {
throw new TypeError(callback + " is not a function");
}
// 1. Let O be ? ToObject(this value).
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// Steps 3, 4, 5, 6, 7
var k = 0;
var value;
if (arguments.length >= 2) {
value = arguments[1];
} else {
while (k < len && !(k in o)) {
k++;
}
// 3. If len is 0 and initialValue is not present,
// throw a TypeError exception.
if (k >= len) {
throw new TypeError(
"Reduce of empty array " + "with no initial value",
);
}
value = o[k++];
}
// 8. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kPresent be ? HasProperty(O, Pk).
// c. If kPresent is true, then
// i. Let kValue be ? Get(O, Pk).
// ii. Let accumulator be ? Call(
// callbackfn, undefined,
// « accumulator, kValue, k, O »).
if (k in o) {
value = callback(value, o[k], k, o);
}
// d. Increase k by 1.
k++;
}
// 9. Return accumulator.
return value;
},
});
}
妿ééè¦æ¯æ´èèå°ä¸æ¯æ´ Object.defineProperty
ç JavaScript å¼æï¼æå¥½ä¸è¦ polyfill Array.prototype
æ¹æ³ï¼å çºä½ ç¡æ³ä»¤å
¶ä¸å¯æèï¼non-enumerableï¼ã
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4