reduce按条件分组输出错误,为什么?

2023-06-27 325 0

要求:

const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 },
  { name: 'David', age: 25 },
  { name: 'Emily', age: 30 }
];
// Output: {
//   25: [{ name: 'Alice', age: 25 }, { name: 'David', age: 25 }],
//   30: [{ name: 'Bob', age: 30 }, { name: 'Emily', age: 30 }],
//   35: [{ name: 'Charlie', age: 35 }]
// }

代码:

let fn = (arr = []) => {
  return arr.reduce((accumulator, currentValue) => {
    return accumulator[currentValue.age]
      ? (accumulator[currentValue.age] = accumulator[currentValue.age].concat(currentValue))
      : ((accumulator[currentValue.age] = [currentValue]));
  }, {});
};
const people = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 30 },
  { name: 'Charlie', age: 35 },
  { name: 'David', age: 25 },
  { name: 'Emily', age: 30 }
];
console.log(fn(people));

输出:
[ { name: 'Emily', age: 30 } ]

accumulator
上一次调用 callbackFn 的结果。在第一次调用时,如果指定了 initialValue 则为指定的值,否则为 array[0] 的值。—— MDN

所谓上一次调用结果即你每一次return的值会交给下一次迭代,而在你的代码中第一次accumulator是初始值{},而在你的return语句是三元表达式,而表达式是赋值语句,赋值语句的结果是等号右侧的结果,一个是concat,一个是[currentValue],这两个都是数组,它们作为下一次的accumulator,所以你下一次迭代就不再是对象了。所以你需要把每次迭代的对象return回去:

let fn = (arr = []) => {
  return arr.reduce((accumulator, currentValue) => {
    return (accumulator[currentValue.age]
      ? (accumulator[currentValue.age] = accumulator[currentValue.age].concat(currentValue))
      : ((accumulator[currentValue.age] = [currentValue])),
    accumulator);
  }, {});
};
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
{ name: 'David', age: 25 },
{ name: 'Emily', age: 30 }
];
let arr = people.reduce((prev,curr) => {
let key = curr["age"];
if (!prev[key]) {
prev[key] = []
}
prev[key].push(curr);
return prev
},{})

你的错误在于三元表达式返回的值是数组,而你把这个数组再返回了,导致下一次接受的 accumulator 是数组而不是对象,原对象的信息实际上已经丢失。

function reduceByAge(list = []){
  return list.reduce(( reduced, present) => {
    const {
      [present.age]: subList = []
    } = reduced;
    subList.push(present);
    reduced[present.age] = subList;
    return reduced;
  }, {});
}
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 35 },
{ name: 'David', age: 25 },
{ name: 'Emily', age: 30 }
];
let fn = (arr = []) => {
return arr.reduce((accumulator, currentValue) => {
let { age } = currentValue;
accumulator[age] ? accumulator[age].push(currentValue): accumulator[age] = [currentValue]
return accumulator;
}, {});
};
console.log(fn(people))

回答

相关文章

nuxt2部署静态化和ssr的时候访问首页先报404再出现首页为什么?
`clip-path` 如何绘制圆角平行四边形呢?
多线程wait方法报错?
VUE 绑定的方法如何直接使用外部函数?
vue2固定定位该怎么做?
谁有redis实现信号量的代码,希望借鉴一下?