根据条件在嵌套的 JS 数组中插入新的 JSON 个对象

Insert new JSON objects in nested JS array based on condition

对于我的电子商务应用程序要求之一,我有一个嵌套数组(示例):

const data = [
    {
        "id": 1,
        "group": "upper-wear",
        "labels": [
            {
                "type": "shirts",
                "quantity": "20",
            },
        ],
        popular: true
    },
    {
        "id": 2,
        "group": "bottom-wear",
        "lables": [
            {
                "type": "trousers",
                "quantity": "31",
            },
        ],
        popular: true
    },
]

对于这个数组,如果组值等于'upper-wear',我需要向数组'labels'插入新对象。

const newDataToInsert = [
    {
      "type": 'blazers',
      "quantity": 19
    },
  ]

这是我到目前为止尝试过的,考虑到现在我只需要插入到单个标签(即'upper-wear')(将来,可以有多个标签类别'upper-wear','bottom-wear', 待插入):

const updatedArray = data.map((datum) => {
    if (datum.group === 'upper-wear') {
      return {
        ...datum,
        labels: [...datum.labels, ...newDataToInsert]
      };
    }
  });
  
  console.log(updatedArray);

但是我似乎遗漏了一个愚蠢的问题,结果 returns 是这样的:

[
  {
    id: 1,
    group: 'upper-wear',
    labels: [ [Object], [Object] ],
    popular: true
  },
  undefined
]

我知道可能有更好的方法可用,但这是我目前认为的最低解决方案。

任何解决当前或任何更好解决方案的帮助将不胜感激。

试试这个

updatedArray = data.map((d) => {
    if (d.group && d.group === 'upper-wear') {
        return { ...d, labels: d.labels.concat(newDataToInsert) }
    } else {
        return d;
    }
})

const data = [
{
    "id": 1,
    "group": "upper-wear",
    "labels": [
        {
            "type": "shirts",
            "quantity": "20",
        },
    ],
    popular: true
},
{
    "id": 2,
    "group": "bottom-wear",
    "lables": [
        {
            "type": "trousers",
            "quantity": "31",
        },
    ],
    popular: true
},
];

const newDataToInsert = [
{
  "type": 'blazers',
  "quantity": 19
},
  ];

const updatedArray = data.map((d) => {
if (d.group && d.group === 'upper-wear') {
    return { ...d, labels: d.labels.concat(newDataToInsert) }
} else {
    return d;
}
});
  console.log(updatedArray)

说明

此处在映射 data 时,我们检查条件

IF

  • 如果匹配,我们将首先从变量中复制整个对象 b return { ...b }
  • 之后我们取另一个同名变量lables return { ...d, labels: d.labels.concat(newDataToInsert) },根据JSON默认性质,同名的新变量将保存最新值
  • 这里在labels中我们首先获取旧数据的副本,然后将其与newDataToInsert数组labels: d.labels.concat(newDataToInsert)合并,它将合并2个数组并将它们存储在JSON中,名称为labels

其他

  • 否则我们只是 return 当前值 else { return d; }

您没有返回地图中的所有对象。您仅在满足条件时才返回结果。这会导致您的未定义对象...

const data = [
    { "id": 1, "group": "upper-wear", "labels": [ { "type": "shirts", "quantity": "20", }, ], popular: true },
    { "id": 2, "group": "bottom-wear", "lables": [ { "type": "trousers", "quantity": "31", }, ], popular: true },
]

const newDataToInsert = [ { "type": 'blazers',"quantity": 19 }, ]

const updatedArray = data.map(datum => { 
    if (datum.group === 'upper-wear') datum.labels = [...datum.labels,  ...newDataToInsert]
    return datum     
});
  
console.log(updatedArray);

您实际上不需要用 map 遍历数组。只需在数组中找到一个对象并更改您想要的内容即可。

const data=[{id:1,group:"upper-wear",labels:[{type:"shirts",quantity:"20"}],popular:true},{id:2,group:"bottom-wear",lables:[{type:"trousers",quantity:"31"}],popular:true}];
const newDataToInsert=[{type:"blazers",quantity:19}];

data.find(({ group }) => group === 'upper-wear')?.labels.push(...newDataToInsert);

console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }

您可以使用 Array#find 找到所需的组,然后更改找到的组的标签。根据您要插入的项目数,有两个选项。使用 Array#push 添加所需的项目;对不止一项使用 forEach

const searchgroup = "upper-wear";
const target = data.find(({group}) => group === searchgroup);
target.labels.push(...newDataToInsert); //For one item to insert
//newDataToInsert.forEach(label => target.labels.push( label )); //For more than one item

const data = [{"id": 1, "group": "upper-wear", "labels": [{"type": "shirts", "quantity": "20"},],popular: true }, {"id": 2, "group": "bottom-wear", "lables": [{"type": "trousers", "quantity": "31", },],popular: true}];

const newDataToInsert = [{"type": 'blazers', "quantity": 19}];

//group to find
const searchgroup = "upper-wear";
//target element in data
const target = data.find(({group}) => group === searchgroup);
//check if group was found
if( target ) {
    //if there's only one product in newDataToInsert us this:
    //target.labels.push(...newDataToInsert);

    //if you have more than one product to be inserted use this; also works for one
    newDataToInsert.forEach(label => target.labels.push( label ));
} else {
    console.log( `No such group found: ${searchgroup}!` );
}

console.log( data );