记录 reduce 用法
1 /** 2 * 3 * reduce(callback, initVal) 第一个参数是回调函数。第二个参数是初始值,如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。 4 * callback接收四个参数: 5 * 1、accumulate:累计器。截止当前元素,之前所有的元数组元素被回调函数处理累计的结果。 6 * 2、current:当前被执行的数组元素。 7 * 3、currentIndex:当前被执行的数组元素索引。 8 * 4、sourceArray:原数组,也就是调用reduce方法的数组 9 */
1 /** 2 * 累加 3 */ 4 let addition = (arr) => arr.reduce((t, v) => t + v) 5 let addition1 = (arr) => arr.reduce((t, v) => t + v, 5) 6 let addition2 = (arr) => arr.reduce((t, v) => t + v.age, 0) 7 console.log(addition([1, 2, 3, 4])); // 10 8 console.log(addition1([1, 2, 3, 4, 5])); // 20 9 console.log(addition2([{age: 10}, {age: 20}])); // 30
1 /** 2 * 累乘 3 */ 4 let multip = (arr) => arr.reduce((t, v) => t * v) 5 let multip1 = (arr) => arr.reduce((t, v) => t * v, 2) 6 console.log(multip([1, 2, 3, 4])); // 24 7 console.log(multip1([1, 2, 3, 4])); // 48
1 /** 2 * 求和 3 */ 4 let list = [ 5 {name: 'aa', id: 5, age: 11}, 6 {name: 'bb', id: 6, age: 12}, 7 {name: 'cc', id: 7, age: 13} 8 ] 9 let total = (arr) => arr.reduce((t, v) => t + v.id * v.age, 0) 10 console.log(total(list)); // 218
1 /** 2 * 数组、字符串 倒叙 3 */ 4 let reverseArr = (arr) => arr.reduceRight((t, v) => (t.push(v), t), []) 5 let reverseStr = (val) => [].reduceRight.call(val, (t, v) => t + v, '') 6 let reverseStr1 = (val) => val.split('').reduceRight((t, v) => t + v) 7 console.log(reverseArr([1, 2, 3, 4])); // [4, 3, 2, 1] 8 console.log(reverseStr('reduce')); // ecuder 9 console.log(reverseStr1('reduce')); // ecuder
1 /** 2 * reduce 实现 map 和 filter 3 */ 4 let list_1 = [1, 2, 3, 4] 5 6 let m = list_1.map(item => item * 2) 7 let m1 = list_1.reduce((t, v) => [...t, v * 2], []) 8 console.log(m, m1); // [2, 4, 6, 8] [2, 4, 6, 8] 9 10 let f = list_1.filter(item => item > 2) 11 let f1 = list_1.reduce((t, v) => v > 2 ? [...t, v] : t, []) 12 console.log(f, f1); // [3, 4] [3, 4] 13 14 let mf = list_1.map(item => item * 2).filter(item => item > 2) 15 let mf1 = list_1.reduce((t, v) => v * 2 > 2 ? [...t, v * 2] : t, []) 16 console.log(mf, mf1); // [4, 6, 8] [4, 6, 8]
1 /** 2 * reduce 实现 some 和 every 3 */ 4 let s = list.some(item => item.age > 12) 5 let s1 = list.reduce((t, v) => t || v.age > 12, false) 6 console.log(s, s1); // true true 7 8 let e = list.every(item => item.age > 12) 9 let e1 = list.reduce((t, v) => t && v.age > 12, true) 10 console.log(e, e1); // false false
1 /** 2 * 数组分割 3 */ 4 let seg = (arr, len = 1) => { 5 return arr.length 6 ? arr.reduce((t, v) => (t[t.length - 1].length === len ? t.push([v]) : t[t.length - 1].push(v), t), [[]]) 7 : [] 8 } 9 console.log(seg([1, 2, 3, 4, 5], 3)); // [[1, 2, 3], [4, 5]]
1 /** 2 * 求数组并集、交集 3 */ 4 let union = (arr1 = [], arr2 = []) => arr1.reduce((t, v) => (!arr2.includes(v) && t.push(v), t), []) 5 console.log(union([1, 2, 3, 4], [1, 4])); // [2, 3] 6 7 let inter = (arr1 = [], arr2 = []) => arr1.reduce((t, v) => (arr2.includes(v) && t.push(v), t), []) 8 console.log(inter([1, 2, 3, 4], [1, 4])); // [1, 4]
1 /** 2 * 替换数组元素 3 */ 4 let rep = (arr = [], val = '', start = 0, end = arr.length) => { 5 if (start < 0 || start >= end || end > arr.length) { 6 return arr 7 } 8 9 return [ 10 ...arr.slice(0, start), 11 ...arr.slice(start, end).reduce((t, v) => (t.push(val || v), t), []), 12 ...arr.slice(end, arr.length) 13 ] 14 } 15 console.log(rep([1, 2, 3, 4, 5], 'q', 1, 3)); // [1, "q", "q", 4, 5]
1 /** 2 * 扁平化数组 3 */ 4 let flat = (arr) => arr.reduce((t, v) => t.concat(Array.isArray(v) ? flat(v) : v), []) 5 console.log(flat([1, [2, [3, 'a']], [2, [5, [6, ['c', 'd']]]]])); // [1, 2, 3, "a", 2, 5, 6, "c", "d"]
1 /** 2 * 数组去重 3 */ 4 let arr3 = (arr) => arr.reduce((t, v) => t.includes(v) ? t : [...t, v], []) 5 console.log(arr3([1, 'a', 'a', 2, 2])); // [1, "a", 2] 6 7 let list_2 = [ 8 {name: 'aa', width: 20}, 9 {name: 'bb', width: 80}, 10 {name: 'cc', width: 10}, 11 {name: 'aa', width: 30}, 12 {name: 'bb', width: 50}, 13 {name: 'cc', width: 70}, 14 {name: 'aa', width: 60}, 15 ] 16 let obj = {} 17 18 let arr4 = (arr) => arr.reduce((t, v) => { 19 if (obj[v.name]) { 20 obj[v.name]++ 21 return t 22 } 23 obj[v.name] = true 24 return [...t, v] 25 }, []) 26 console.log(arr4(list_2)); // [{name: 'aa', width: 20}, {name: 'bb', width: 80}, {name: 'cc', width: 10}] 27 28 let arr5 = (arr) => arr.reduce((t, v) => { 29 if (!obj[v.name]) { 30 t.push(v) 31 obj[v.name] = true 32 } 33 return t 34 }, []) 35 console.log(arr5(list_2)); // [{name: 'aa', width: 20}, {name: 'bb', width: 80}, {name: 'cc', width: 10}]
1 /** 2 * 最大、最小值 3 */ 4 let max = (arr) => arr.reduce((t, v) => t > v ? t : v) 5 let min = (arr) => arr.reduce((t, v) => t < v ? t : v) 6 console.log(max([1, 22, 33, 44])); // 44 7 console.log(min([1, 22, 33, 44])); // 1 8 9 let max1 = (arr) => arr.reduce((t, v) => t.age > v.age ? t : v, []) 10 let min1 =(arr) => arr.reduce((t, v) => t.age < v.age ? t : v, []) 11 console.log(max1([{age: 10}, {age: 20}, {age: 30}])); // {age: 30} 12 console.log(min1([{age: 10}, {age: 20}, {age: 30}])); // {age: 10}
1 /** 2 * 数组成员拆解 3 */ 4 let zip = (arr) => arr.reduce( 5 (t, v) => (v.forEach((item, i) => t[i].push(item)), t), 6 Array.from({length: Math.max(...arr.map(m => m.length))}).map(v => []) 7 ) 8 console.log(zip([['a', 1], ['b', 2]])); // [['a', 'b'], [1, 2]]
1 /** 2 * 统计个数 3 */ 4 let count = (arr) => arr.reduce((t, v) => (t[v] = (t[v] || 0) + 1, t), {}) 5 console.log(count(['a', 'a', 'b', 'c', 'c'])); // {a: 2, b: 1, c: 2}
1 /** 2 * 查找数组成员位置 3 */ 4 let local = (arr, val) => arr.reduce((t, v, i) => (v === val && t.push(i), t), []) 5 console.log(local([1, 2, 3, 3, 2, 1], 1)); // [0, 5]
1 /** 2 * 相同属性分组 3 */ 4 let list_3 = [ 5 { name: 'a', age: 10 }, 6 { name: 'b', age: 14 }, 7 { name: 'c', age: 17 }, 8 { name: 'a', age: 12 }, 9 { name: 'c', age: 19 } 10 ] 11 let attr = (arr, key) => { 12 return key 13 ? arr.reduce((t, v) => (!t[v[key]] && (t[v[key]] = []), t[v[key]].push(v), t), {}) 14 : {} 15 } 16 console.log(attr(list_3, 'name')); 17 // { 18 // a: [{ name: 'a', age: 10 }, { name: 'a', age: 12 }], 19 // b: [{ name: 'b', age: 14 }], 20 // c: [{ name: 'c', age: 17 }, { name: 'c', age: 19 }] 21 // }
1 /** 2 * 异步累计 3 */ 4 async function asyncTotal(arr = []) { 5 return arr.reduce(async (t, v) => { 6 let total = await t 7 let item = await Todo(v) 8 total[v] = item 9 return total 10 }, Promise.resolve({})) 11 } 12 // let res = await asyncTotal([1,2,3,4,5]) // 需要在 async 下使用
1 /** 2 * 斐波那契数列 3 */ 4 let fiboSeq = (length = 5) => { 5 let arr = [...new Array(length).keys()] 6 return arr.reduce((t, v, i) => (i > 1 && t.push(t[i - 1] + t[i - 2]), t), [0, 1]) 7 } 8 console.log(fiboSeq(10)); // [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
1 /** 2 * URL参数反序列化 3 */ 4 let paramsURL = () => { 5 return location.search.replace(/(^\?)|(&$)/g, '').split('&').reduce((t, v) => { 6 let [key, val] = v.split('=') 7 t[key] = decodeURIComponent(val) 8 return t 9 }, {}) 10 } 11 // location: www.baidu.com?a=11&b=22 12 console.log(paramsURL()); // {a: '11', b: '22'}
1 /** 2 * URl参数序列化 3 */ 4 let stringifyURL = (value) => { 5 return Object.entries(value) 6 .reduce((t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`, Object.keys(value).length ? '?' : '') 7 .replace(/&$/, '') 8 } 9 console.log(stringifyURL({a: '11', b: '22'})); // '?a=11&b=22'
1 /** 2 * 返回对象指定键 3 */ 4 let keys = (obj, arr) => { 5 return Object.keys(obj) 6 .reduce((t, v) => (arr.includes(v) && (t[v] = obj[v]), t), {}) 7 } 8 console.log(keys({a: 1, b: 2, c: 3, d: 4}, ['a', 'c'])); // {a: 1, c: 3}
1 /** 2 * 数组转对象 3 */ 4 let obj5 = (arr) => arr.reduce((t, v) => { 5 let {name, ...rest} = v 6 t[name] = rest 7 return t 8 }, {}) 9 console.log(obj5(list_3)); 10 // { 11 // a: {age: 12}, 12 // b: {age: 14}, 13 // c: {age: 19} 14 // }
1 // 数组子集求和 2 let arr = [1, 2, 3] 3 let total2 = arr.reduce((t, v) => t.concat(t.map(m => m.concat(v))), [[]]) 4 console.log(total2); // [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
1 /** 2 * 九九乘法表 3 */ 4 let arr99 = [...new Array(9).keys()] 5 .reduce((t, v, i) => t + [...new Array(i + 1).keys()] 6 .reduce((x, y, z) => `${x}${i + 1} * ${z + 1} = ${(i + 1) * (z + 1)} `, '') 7 .trim() + '\n', '\n') 8 9 console.log(arr99); 10 11 // 1 * 1 = 1 12 // 2 * 1 = 2 2 * 2 = 4 13 // 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9 14 // 4 * 1 = 4 4 * 2 = 8 4 * 3 = 12 4 * 4 = 16 15 // 5 * 1 = 5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 16 // 6 * 1 = 6 6 * 2 = 12 6 * 3 = 18 6 * 4 = 24 6 * 5 = 30 6 * 6 = 36 17 // 7 * 1 = 7 7 * 2 = 14 7 * 3 = 21 7 * 4 = 28 7 * 5 = 35 7 * 6 = 42 7 * 7 = 49 18 // 8 * 1 = 8 8 * 2 = 16 8 * 3 = 24 8 * 4 = 32 8 * 5 = 40 8 * 6 = 48 8 * 7 = 56 8 * 8 = 64 19 // 9 * 1 = 9 9 * 2 = 18 9 * 3 = 27 9 * 4 = 36 9 * 5 = 45 9 * 6 = 54 9 * 7 = 63 9 * 8 = 72 9 * 9 = 81