巧用 Array reduce
原创
2023-3-8
16:08
编辑于
2023-3-8
17:08
数组的实例方法 reduce 是在ECMAScript 5 中添加的,注意 reduce 的参数是可以传多个的。
var arr = [1, 2, 3, 4, 5]
arr.reduce((accumulator, currentValue, currentIndex, array) => {
}, initialValue)
accumulator
:上一次调用返回的值。在第一次调用时,initialValue如果未指定,则为array[0]currentValue
:当前元素的值。第一次调用时,如果指定了 initialValue,此时currentValue为 initialValue,否则为array[1]currentIndex
:currentValue在数组中的索引位置。第一次调用时,如果指定了 initialValue,则为0,否则为1- 被调用的数组
initialValue
:第一次调用初始化值
最经典的用法是求和,相比for循环,代码非常简洁。
const arr = [1, 2, 3, 4, 5];
const sum = arr.reduce((acc, cur) => acc + cur, 0);
console.log(sum); // 15
除了上面最基础的用法,利用好第二个参数,也就是初始值,可以在很多场景下提升编码效率。
二位键值数组转成对象
const arr = [['a', 1], ['b', 2], ['c', 3]]
const obj = {}
arr.reduce((r, [k, v]) => {
r[k] = v
return obj
}, obj)
// {a: 1, b: 2, c: 3}
深层获取对象的属性值
const obj = {
a: {
b: {
c: {
d: '1'
},
e: null
}
}
}
function getValue(target, key) {
try {
return key.split('.').reduce((r, k) => r[k], target)
} catch (e) {
return undefined
}
}
getValue(obj, 'a.b.c.d') // 1
getValue(obj, 'a.b.e') // null
getValue(obj, 'a.b.e.f') // undefined
同样可以用来深层赋值
function setValue(target, key, value) {
const path = key.split('.')
path.reduce((r, k, idx) => {
if (idx === path.length - 1) {
r[k] = value
} else {
if (r[k] === null || typeof r[k] !== 'object') {
r[k] = {}
}
return r[k]
}
}, target)
}
const t = {}
setValue(t, 'a.b.c.e.f', 1)
setValue(t, 'a.b.c.g', 2)
console.log('t: ', t);
{
"a": {
"b": {
"c": {
"e": {
"f": 1
},
"g": 2
}
}
}
}
数组去重
const arr = [1, 2, 2, 3, 4, 4, 5];
const uniqueArr = arr.reduce((acc, cur) => {
if (!acc.includes(cur)) {
acc.push(cur);
}
return acc;
}, []);
console.log(uniqueArr); // [1, 2, 3, 4, 5]
当然,现在可以通过 Set 来去重。
数组分组
const arr = ['a', 'b', 'c', 'd', 'e'];
const groups = arr.reduce((acc, cur) => {
const index = cur.charCodeAt(0) % 2;
acc[index].push(cur);
return acc;
}, [[], []]);
console.log(groups); // [['a', 'c', 'e'], ['b', 'd']]
关注我的公众号