reduce解决读取多层嵌套对象属性

        在使用reduce时突然发现reduce似乎可以遍历对象嵌套结构

function getObjectPropertyValue(obj, propertyPath) {
  return propertyPath.split('.').reduce((result, key) => result[key], obj);
}

const person = {
  name: 'John',
  address: {
    city: 'New York',
    street: '123 ABC Street'
  }
};

const name = getObjectPropertyValue(person, 'name');
console.log(name); // John

const city = getObjectPropertyValue(person, 'address.city');
console.log(city); // New York

const street = getObjectPropertyValue(person, 'address.street');
console.log(street); // 123 ABC Street

        查询文档:Array methods

reduce/reduceRight

When we need to iterate over an array – we can use forEachfor or for..of.

When we need to iterate and return the data for each element – we can use map.

The methods arr.reduce and arr.reduceRight also belong to that breed, but are a little bit more intricate. They are used to calculate a single value based on the array.

The syntax is:

let value = arr.reduce(function(accumulator, item, index, array) {
  // ...
}, [initial]);

The function is applied to all array elements one after another and “carries on” its result to the next call.

Arguments:

  • accumulator – is the result of the previous function call, equals initial the first time (if initial is provided).
  • item – is the current array item.
  • index – is its position.
  • array – is the array.

As function is applied, the result of the previous function call is passed to the next one as the first argument.

So, the first argument is essentially the accumulator that stores the combined result of all previous executions. And at the end it becomes the result of reduce.

Sounds complicated?

The easiest way to grasp that is by example.

Here we get a sum of an array in one line:

let arr = [1, 2, 3, 4, 5];

let result = arr.reduce((sum, current) => sum + current, 0);

alert(result); // 15

The function passed to reduce uses only 2 arguments, that’s typically enough.

Let’s see the details of what’s going on.

  1. On the first run, sum is the initial value (the last argument of reduce), equals 0, and current is the first array element, equals 1. So the function result is 1.
  2. On the second run, sum = 1, we add the second array element (2) to it and return.
  3. On the 3rd run, sum = 3 and we add one more element to it, and so on…

The calculation flow:

Or in the form of a table, where each row represents a function call on the next array element:

sumcurrentresult
the first call011
the second call123
the third call336
the fourth call6410
the fifth call10515

Here we can clearly see how the result of the previous call becomes the first argument of the next one.

We also can omit the initial value:

let arr = [1, 2, 3, 4, 5];

// removed initial value from reduce (no 0)
let result = arr.reduce((sum, current) => sum + current);

alert( result ); // 15

The result is the same. That’s because if there’s no initial, then reduce takes the first element of the array as the initial value and starts the iteration from the 2nd element.

The calculation table is the same as above, minus the first row.

But such use requires an extreme care. If the array is empty, then reduce call without initial value gives an error.

Here’s an example:

let arr = [];

// Error: Reduce of empty array with no initial value
// if the initial value existed, reduce would return it for the empty arr.
arr.reduce((sum, current) => sum + current);

So it’s advised to always specify the initial value.

The method arr.reduceRight does the same, but goes from right to left.

        可以看出官方推荐的用法是使用这个累加器可以方便的计算一个数组元素的和,通过 return 可以把每次迭代的值返回给total作为下一次的初始值,如果我们 return 一个对象的话,不就可以依次读取多层嵌套的对象的属性了吗? 

        我们将子级结构作为上一次的值返回,从而实现遍历多层嵌套结构。在reduce函数的回调函数中,根据需要选择将子级结构与累积值(上一次的值)进行合并或者进行其他操作,并将结果作为下一次迭代的累积值返回。

        另外reduce还可以实现数据转换与映射,使用 reduce 函数将一个数据集转换为另一种格式的数据集:

const people = [
  { name: 'John', age: 25 },
  { name: 'Jane', age: 30 },
  { name: 'Mike', age: 35 }
];
const nameAgeMap = people.reduce((acc, curr) => {
  acc[curr.name] = curr.age;
  return acc;
}, {});
console.log(nameAgeMap); // { John: 25, Jane: 30, Mike: 35 }
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leviash

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值