① reduce()方法
1、語法
arr.reduce(callback,[initialValue])
複製程式碼
reduce
為陣列中的每一個元素依次執行回撥函式,不包括陣列中被刪除或從未被賦值的元素,接受四個引數:初始值(或者上一次回撥函式的返回值),當前元素值,當前索引,呼叫 reduce
的陣列。
callback (執行陣列中每個值的函式,包含四個引數)
1、previousValue (上一次呼叫回撥返回的值(沒有提供initialValue),或者是提供的初始值(initialValue))
2、currentValue (陣列中當前被處理的元素)
3、index (當前元素在陣列中的索引)
4、array (呼叫 reduce 的陣列)
initialValue (作為第一次呼叫 callback 的第一個引數。)
複製程式碼
2、例項解析 initialValue 引數
-
沒有提供initialValue引數
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次。
結論:如果沒有提供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"
複製程式碼
但是要是我們設定了初始值就不會報錯,如下:
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
複製程式碼
所以一般來說我們提供初始值通常更安全
3、reduce的高階用法
-
計算陣列中每個元素出現的次數
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()方法
filter
為陣列中的每個元素呼叫一次 callback
函式,並利用所有使得 callback
返回 true 或 等價於 true 的值 的元素建立一個新陣列。callback
只會在已經賦值的索引上被呼叫,對於那些已經被刪除或者從未被賦值的索引不會被呼叫。那些沒有通過 callback
測試的元素會被跳過,不會被包含在新陣列中。
1、引數
callback
用來測試陣列的每個元素的函式。呼叫時使用引數 (element, index, array)。
複製程式碼
返回true表示保留該元素(通過測試),false則不保留。它接受三個引數:
**element**
當前在陣列中處理的元素。
**index**可選
正在處理元素在陣列中的索引。
**array**可選
呼叫了`filter`的陣列。
複製程式碼
thisArg
可選
可選。執行 `callback` 時的用於 `this` 的值。
複製程式碼
2、返回值
一個新的通過測試的元素的集合的陣列,如果沒有通過測試則返回空陣列
3、返回值
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
遍歷到它們那一刻的值。被刪除或從來未被賦值的元素不會被遍歷到。
4、示例
- 篩選排除所有的小值
function isBigEnough(element) {
return element >= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered is [12, 130, 44]
複製程式碼
- 過濾JSON中的無效條目
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']
複製程式碼
- GitHub: 歡迎Star wq93