【问题标题】:Reduce array of objects to unique keys and add array of values common to that key将对象数组减少为唯一键并添加该键共有的值数组
【发布时间】:2021-02-26 21:35:56
【问题描述】:

我想将该数组的值按其car 分组 键,然后将该汽车的通用值推送到值数组中。

我设法做到了这一点,但想知道是否有更简单的方法来使用 reduce。

const arr = [{
  car: 'audi',
  value: 'black'
}, {
  car: 'audi',
  value: 'expensive'
}, {
  car: 'fiat',
  value: 'red'
}, {
  car: 'fiat',
  value: 'cheap'
}]

// Simple array with unique car
const cars = Array.from(new Set(arr.map(({ car }) => car)))
// Array of objects with unique `car` and an empty `values` array for each
const result = cars.map((car) => ({ car, values: [] }))

// Push to values array the `value` for each car
arr.map((obj) => {
  result.map((res) => {
    if (obj.car === res.car) {
      res.values.push(obj.value)
    }
  })
})

console.log(result)
/*
[{
  car: 'audi',
  values: ['black', 'expensive']
}, {
  car: 'fiat',
  values: ['red', 'cheap']
}]
*/

【问题讨论】:

    标签: javascript ecmascript-6 reduce ecmascript-5


    【解决方案1】:

    创建一个由car 名称索引的对象,然后遍历原始数组,将值推送到对象上的数组中:

    const arr = [{
      car: 'audi',
      value: 'black'
    }, {
      car: 'audi',
      value: 'expensive'
    }, {
      car: 'fiat',
      value: 'red'
    }, {
      car: 'fiat',
      value: 'cheap'
    }];
    
    const carsByName = {};
    for (const { car, value } of arr) {
      if (!carsByName[car]) carsByName[car] = { car, value: [] };
      carsByName[car].value.push(value);
    }
    console.log(Object.values(carsByName));

    虽然这可以reduce完成,但可以说是not very semantically appropriate,当累加器永远不会改变时(并且在语法上有点吵):

    const arr = [{
      car: 'audi',
      value: 'black'
    }, {
      car: 'audi',
      value: 'expensive'
    }, {
      car: 'fiat',
      value: 'red'
    }, {
      car: 'fiat',
      value: 'cheap'
    }];
    
    const carsByName = arr.reduce((a, { car, value }) => {
      if (!a[car]) a[car] = { car, value: [] };
      a[car].value.push(value);
      return a;
    }, {});
    console.log(Object.values(carsByName));

    【讨论】:

    • 谢谢,看起来不错,我可以用 [carsByName] 代替 Object.values(carsByName) 吗?
    • 这将为您提供一个包含单个对象的数组,该对象由汽车名称索引。如果该数据结构是您想要的,那就去做吧,但这不是您在问题中的预期输出。
    • 你是对的,非常感谢代码运行良好
    【解决方案2】:

    您可以使用.reducecar 对项目进行分组,然后使用.map 创建具有car 及其values 的对象列表:

    const arr = [{
      car: 'audi',
      value: 'black'
    }, {
      car: 'audi',
      value: 'expensive'
    }, {
      car: 'fiat',
      value: 'red'
    }, {
      car: 'fiat',
      value: 'cheap'
    }]
    
    let result = arr.reduce((acc,item) => {
      const values = acc[item.car];
      acc[item.car] = values ? [...values, item.value] : [item.value];
      return acc;
    }, {});
    
    result = Object.entries(result).map(([car, values]) => ({car,values}));
    
    console.log(result)

    【讨论】:

      【解决方案3】:

      只需使用 reduce 即可。保留acc 带有钥匙carvalues 的汽车数组。然后映射它。我的意思是:

      const arr = [
        {
          car: "audi",
          value: "black",
        },
        {
          car: "audi",
          value: "expensive",
        },
        {
          car: "fiat",
          value: "red",
        },
        {
          car: "fiat",
          value: "cheap",
        },
      ];
      
      const result = Object.entries(
        arr.reduce((acc, { car, value }) => {
          if (acc[car]) {
            return {
              ...acc,
              [car]: [...acc[car], value],
            };
          }
      
          return { ...acc, [car]: [value] };
        }, [])
      ).map(([car, values]) => ({ car, values }));
      
      console.log(result);

      【讨论】:

        猜你喜欢
        • 2016-10-02
        • 2020-03-25
        • 1970-01-01
        • 1970-01-01
        • 2022-12-28
        • 2022-06-10
        • 1970-01-01
        • 2022-11-27
        • 1970-01-01
        相关资源
        最近更新 更多