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