You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从单个JavaScript对象中提取同类数据生成数组

问题:从对象提取同类商品数组时仅保留最后一个元素

问题场景

需要从以下大型对象(moreProductInfo1)中提取同类商品数据,整理为包含商品对象的数组:

{
    "SKU1": "1",
    "productId1": "2",
    "condition1": "Refurbrished",
    "price1": "3",
    "quantity1": "4",
    "colorMap1": "5",
    "SKU2": "11",
    "SKU3": "111",
    "productId2": "22",
    "productId3": "222",
    "condition2": "Old",
    "condition3": "Used",
    "price2": "33",
    "price3": "333",
    "quantity2": "44",
    "quantity3": "444",
    "colorMap2": "55",
    "colorMap3": "555"
}

期望得到的结果:

[{
    "SKU": "1",
    "productId": "2",
    "condition": "Refurbrished",
    "price": "3",
    "quantity": "4",
    "colorMap": "5",
    "attribute": "Color",
    "attributeValue": "violet"
},
{
    "SKU": "11",
    "productId": "22",
    "condition": "Old",
    "price": "33",
    "quantity": "44",
    "colorMap": "55",
    "attribute": "Quality",
    "attributeValue": "New"
},
{
    "SKU": "111",
    "productId": "222",
    "condition": "Used",
    "price": "333",
    "quantity": "444",
    "colorMap": "555",
    "attribute": "Material",
    "attributeValue": "Cotton"
}]

使用addedVariation数组确定商品数量(本次为3个):

[
  {
    "Color": "violet"
  },
  {
    "Quality": "New"
  },
  {
    "Material": "Cotton"
  }
]

尝试的代码如下,但最终结果仅保留最后一个商品对象:

...
const [productsArray, setProductsArray] = useState([]);

...

addedVariation.map((curr, idx, arr) => {

  for (var key of Object?.keys(moreProductInfo1)) {

    if (key?.includes(`${idx + 1}`)) {
      setProductsArray([
        ...productsArray,
        {
          attribute: Object?.keys(curr)?.[idx],
          attributeValue: Object?.values(curr)?.[idx],
          SKU: moreProductInfo1?.[`SKU${idx + 1}`],
          productId: moreProductInfo1?.[`productId${idx + 1}`],
          condition: moreProductInfo1?.[`condition${idx + 1}`],
          price: moreProductInfo1?.[`price${idx + 1}`],
          quantity: moreProductInfo1?.[`quantity${idx + 1}`],
          colorMap: moreProductInfo1?.[`colorMap${idx + 1}`],
        },
      ]);
    }
  }
});

...

问题分析

  1. useState异步更新导致状态覆盖:setProductsArray是异步操作,循环中每次调用时,productsArray始终是初始的空数组,所以每次更新都是[newItem],最终只保留最后一次的结果。
  2. 冗余的键遍历:嵌套for...of遍历moreProductInfo1的键完全没必要,通过idx+1拼接键名就能直接获取对应值。
  3. attribute获取错误:Object.keys(curr)?.[idx]中,curr是单个键值对的对象,idx会超出索引范围(比如第二个对象idx=1,但Object.keys(curr)只有一个元素),导致attribute值为undefined。

解决方案

方案一:先构建完整数组再更新状态(推荐)

先一次性生成所有商品对象的数组,再调用setProductsArray更新状态,避免异步更新的问题:

const [productsArray, setProductsArray] = useState([]);

// 构建商品数组
const newProducts = addedVariation.map((curr, idx) => {
  const suffix = idx + 1;
  // 提取当前variation的键值对
  const [attribute, attributeValue] = Object.entries(curr)[0];
  return {
    attribute,
    attributeValue,
    SKU: moreProductInfo1[`SKU${suffix}`],
    productId: moreProductInfo1[`productId${suffix}`],
    condition: moreProductInfo1[`condition${suffix}`],
    price: moreProductInfo1[`price${suffix}`],
    quantity: moreProductInfo1[`quantity${suffix}`],
    colorMap: moreProductInfo1[`colorMap${suffix}`]
  };
});

// 一次性更新状态
setProductsArray(newProducts);

方案二:使用函数式更新(适合需要逐步更新的场景)

如果必须在循环中更新状态,使用setState的函数式形式,确保每次更新都基于最新的状态:

const [productsArray, setProductsArray] = useState([]);

// 先清空旧数组(按需选择)
setProductsArray([]);

addedVariation.forEach((curr, idx) => {
  const suffix = idx + 1;
  const [attribute, attributeValue] = Object.entries(curr)[0];
  // 函数式更新,基于最新状态添加新元素
  setProductsArray(prevProducts => [
    ...prevProducts,
    {
      attribute,
      attributeValue,
      SKU: moreProductInfo1[`SKU${suffix}`],
      productId: moreProductInfo1[`productId${suffix}`],
      condition: moreProductInfo1[`condition${suffix}`],
      price: moreProductInfo1[`price${suffix}`],
      quantity: moreProductInfo1[`quantity${suffix}`],
      colorMap: moreProductInfo1[`colorMap${suffix}`]
    }
  ]);
});

说明

  • 方案一效率更高,减少状态更新次数,适合一次性生成所有数据的场景。
  • 方案二通过函数式更新prevProducts => [...prevProducts, newItem],确保每次更新都使用最新的数组状态,不会覆盖之前的元素。
  • 用Object.entries(curr)[0]正确提取单个对象的键值对,避免索引错误。

内容的提问来源于stack exchange,提问作者Youzef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:35:16