arr.reduce(callback,[initialValue])
複製代碼
reduce
爲數組中的每個元素依次執行回調函數,不包括數組中被刪除或從未被賦值的元素,接受四個參數:初始值(或者上一次回調函數的返回值),當前元素值,當前索引,調用 reduce
的數組。git
callback (執行數組中每一個值的函數,包含四個參數)
1、previousValue (上一次調用回調返回的值(沒有提供initialValue),或者是提供的初始值(initialValue))
2、currentValue (數組中當前被處理的元素)
3、index (當前元素在數組中的索引)
4、array (調用 reduce 的數組)
initialValue (做爲第一次調用 callback 的第一個參數。)
複製代碼
沒有提供initialValue參數github
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})
console.log(arr, sum);
// 打印結果:
// 1 2 1
// 3 3 2
// 6 4 3
// [1, 2, 3, 4, 5] 15
複製代碼
這裏能夠看出,上面的例子index是從1開始的,第一次的prev的值是數組的第一個值。數組長度是4,可是reduce函數循環3次。數組
提供initialValue參數安全
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
},0) //注意這裏設置了初始值
console.log(arr, sum);
// 打印結果:
// 0 1 0
// 1 2 1
// 3 3 2
// 6 4 3
// [1, 2, 3, 4] 10
複製代碼
這個例子index是從0開始的,第一次的prev的值是咱們設置的初始值0,數組長度是4,reduce函數循環4次。app
結論:若是沒有提供initialValue,reduce 會從索引1的地方開始執行 callback 方法,跳過第一個索引。若是提供initialValue,從索引0開始。
函數
注意:若是這個數組爲空,運用reduce
是什麼狀況?測試
var arr = [];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})
//報錯,"TypeError: Reduce of empty array with no initial value"
複製代碼
可是要是咱們設置了初始值就不會報錯,以下:ui
var arr = [];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
},0)
console.log(arr, sum); // [] 0
複製代碼
因此通常來講咱們提供初始值一般更安全this
計算數組中每一個元素出現的次數spa
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre,cur)=>{
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1
}
return pre
},{})
console.log(nameNum); //{Alice: 2, Bob: 1, Tiff: 1, Bruce: 1}
複製代碼
數組去重
let arr = [1,2,3,4,4,1]
let newArr = arr.reduce((pre,cur)=>{
if(!pre.includes(cur)){
return pre.concat(cur)
}else{
return pre
}
},[])
console.log(newArr);// [1, 2, 3, 4]
//-----------------------------------------------
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]
// 不能使用 pre.push(cur) 由於數組的push方法返回的是新數組的長度,而concat返回的是新數組
複製代碼
將二維數組轉化爲一維
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre,cur)=>{
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
複製代碼
將多維數組轉化爲一維
let arr = [[0, 1], [2, 3], [4,[5,6,7]]]
const newArr = function(arr){
return arr.reduce((pre,cur)=>pre.concat(Array.isArray(cur)?newArr(cur):cur),[])
}
console.log(newArr(arr)); //[0, 1, 2, 3, 4, 5, 6, 7]
複製代碼
對象裏的屬性求和
var result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
var sum = result.reduce(function (prev, cur) {
return cur.score + prev;
}, 0);
console.log(sum) //60
複製代碼
按屬性對object分類
var people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
];
function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
console.log(obj)
var key = obj[property];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
var groupedPeople = groupBy(people, 'age');
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
複製代碼
功能型函數管道
// Building-blocks to use for composition
const double = x => x + x;
const triple = x => 3 * x;
const quadruple = x => 4 * x;
// Function composition enabling pipe functionality
const pipe = (...functions) => input => functions.reduce(
(acc, fn) => fn(acc),
input
);
// 還原函數
// function pipe(...functions) {
// return function (input) {
// return functions.reduce(function (acc, fn) {
// return fn(acc)
// }, input)
// }
// }
// Composed functions for multiplication of specific values
const multiply6 = pipe(double, triple);
const multiply9 = pipe(triple, triple);
const multiply16 = pipe(quadruple, quadruple);
const multiply24 = pipe(double, triple, quadruple);
// Usage
multiply6(6); // 36
multiply9(9); // 81
multiply16(16); // 256
multiply24(10); // 240
複製代碼
filter
爲數組中的每一個元素調用一次 callback
函數,並利用全部使得 callback
返回 true 或 等價於 true 的值 的元素建立一個新數組。callback
只會在已經賦值的索引上被調用,對於那些已經被刪除或者從未被賦值的索引不會被調用。那些沒有經過 callback
測試的元素會被跳過,不會被包含在新數組中。
callback
用來測試數組的每一個元素的函數。調用時使用參數 (element, index, array)。
複製代碼
返回true表示保留該元素(經過測試),false則不保留。它接受三個參數:
**element**
當前在數組中處理的元素。
**index**可選
正在處理元素在數組中的索引。
**array**可選
調用了`filter`的數組。
複製代碼
thisArg
可選
可選。執行 `callback` 時的用於 `this` 的值。
複製代碼
一個新的經過測試的元素的集合的數組,若是沒有經過測試則返回空數組
filter
爲數組中的每一個元素調用一次 callback
函數,並利用全部使得 callback
返回 true 或 等價於 true 的值 的元素建立一個新數組。callback
只會在已經賦值的索引上被調用,對於那些已經被刪除或者從未被賦值的索引不會被調用。那些沒有經過 callback
測試的元素會被跳過,不會被包含在新數組中。
callback
被調用時傳入三個參數:
若是爲 filter
提供一個 thisArg
參數,則它會被做爲 callback
被調用時的 this
值。不然,callback
的 this
值在非嚴格模式下將是全局對象,嚴格模式下爲 undefined
。 callback
最終觀察到的this
值是根據一般函數所看到的 "this"的規則肯定的。
filter
不會改變原數組,它返回過濾後的新數組。
filter
遍歷的元素範圍在第一次調用 callback
以前就已經肯定了。在調用 filter
以後被添加到數組中的元素不會被 filter
遍歷到。若是已經存在的元素被改變了,則他們傳入 callback
的值是 filter
遍歷到它們那一刻的值。被刪除或歷來未被賦值的元素不會被遍歷到。
function isBigEnough(element) {
return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
複製代碼
var arr = [
{ id: 15 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 12.2 },
{ },
{ id: null },
{ id: NaN },
{ id: 'undefined' }
];
var invalidEntries = 0;
function isNumber(obj) {
return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
function filterByID(item) {
if (isNumber(item.id) && item.id !== 0) {
return true;
}
invalidEntries++;
return false;
}
var arrByID = arr.filter(filterByID);
console.log('Filtered Array\n', arrByID);
// Filtered Array
// [{ id: 15 }, { id: -1 }, { id: 3 }, { id: 12.2 }]
console.log('Number of Invalid Entries = ', invalidEntries);
// Number of Invalid Entries = 5
複製代碼
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
/** * Array filters items based on search criteria (query) */
function filterItems(query) {
return fruits.filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
})
}
console.log(filterItems('ap')); // ['apple', 'grapes']
console.log(filterItems('an')); // ['banana', 'mango', 'orange']
複製代碼