我想组合数组中的对象,应该如何更改?

I want to combine the objects in the array, how should I change them?

const data = [
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "13inch",
    optionPrice: 0,
    qty: 2,
  },
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "15inch",
    optionPrice: 1000,
    qty: 1,
  },
]

const results = data.reduce((prev, curr) => {
  if (prev.productId === curr.productId) {
    ???
  }
  
}, []);

输出

  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    option: [
      { optionName: "13inch", optionPrice: 0, qty: 2 },
      { optionName: "15inch", optionPrice: 1000, qty: 1 },
    ],
  },

如果productId与上面代码相​​同,

我想去掉key:value的重叠部分,为不重叠的部分创建一个option对象,为value创建一个数组对象。

我试着用reduce解决了,但是不太顺利,所以我问你一个问题。

一种方法是将array转为object,使用productId作为key:

const data = [
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "13inch",
    optionPrice: 0,
    qty: 2,
  },
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "15inch",
    optionPrice: 1000,
    qty: 1,
  },
  {
    productId: 4,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "15inch",
    optionPrice: 1000,
    qty: 1,
  },
]

const results = Object.values(data.reduce((prev, curr) => {
  if (prev[curr.productId])
  {
    const obj = prev[curr.productId];
    if (!obj.option)
    {
      obj.option = [];
      obj.option.push({optionName: obj.optionName, optionPrice: obj.optionPrice, qty: obj.qty});
      delete obj.optionName;
      delete obj.optionPrice;
      delete obj.qty;
    }
    
    prev[curr.productId].option.push({optionName: curr.optionName, optionPrice: curr.optionPrice, qty: curr.qty});
  }
  else
    prev[curr.productId] = Object.assign({}, curr);

  return prev;
  
}, {}));

console.log(results);

这是一种不会改变现有数组数据的任何部分的纯函数式方法:

function deduplicate (array) {
  const results = [];
  const idCache = new Set();

  for (const item of array) {
    // skip if we've already seen products with the same ID
    if (idCache.has(item.productId)) continue;
    idCache.add(item.productId);
    // get products with matching ID
    const items = array.filter(({productId}) => productId === item.productId);

    // if there were none, store the single product as-is and continue
    if (items.length === 0) {
      results.push({...item});
      continue;
    }

    // add initial product to others, preserving order
    items.unshift(item);
    const merged = {};

    for (const key of Object.keys(item)) {
      const values = items.map(item => item[key]);
      // if all the same value, set it on the merged object
      if (values.every(val => val === item[key])) merged[key] = item[key];
      else {
        // set to property on obj in "options" array
        for (const [idx, val] of values.entries()) {
          ((merged.options ??= [])[idx] ??= {})[key] = val;
        }
      }
    }

    results.push(merged);
  }

  return results;
}

const data = [
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "13inch",
    optionPrice: 0,
    qty: 2,
  },
  {
    productId: 6,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "15inch",
    optionPrice: 1000,
    qty: 1,
  },
  {
    productId: 5,
    productName: "pouch",
    productPrice: 29000,
    discountRate: 19,
    optionName: "15inch",
    optionPrice: 1000,
    qty: 1,
  },
];

const result = deduplicate(data);
console.log(result);

这是您可以做到的一种方法:

const data = [   {     productId: 6,     productName: "pouch",     productPrice: 29000,     discountRate: 19,     optionName: "13inch",     optionPrice: 0,     qty: 2,   },   {     productId: 6,     productName: "pouch",     productPrice: 29000,     discountRate: 19,     optionName: "15inch",     optionPrice: 1000,     qty: 1,   },   {     productId: 4,     productName: "pouch",     productPrice: 29000,     discountRate: 19,     optionName: "15inch",     optionPrice: 1000,     qty: 1,   }, ],

      output = Object.entries(
          data.reduce(
              (prev,{productId,...r}) =>
              ({...prev, [productId]: Object.entries(r).reduce(
                  (acc,[key,value]) =>
                  ({...acc, [key]: prev[productId] && prev[productId][key] ?
                      prev[productId][key] === value ? 
                      value :
                      [prev[productId][key],value] :
                      value
                  }),{})
              }),{}
          )
      )
      .map(
          ([productId,obj]) =>
          ({
              productId, 
              ...Object.entries(obj).reduce(
                  (acc,[key,value]) =>
                  !Array.isArray(value) ? 
                  ({...acc, [key]:value}) : 
                  ({...acc, option:value.map(
                      (v,i) => 
                      acc["option"] ? 
                      ({...acc["option"][i], [key]: v}) :
                      ({[key]: v}))
                  }),
              {})
          })
       );

console.log(output);