简体   繁体   English

将包含空数组的对象数组映射为属性会忽略整个对象

[英]Mapping an array of objects containing an empty array as property ignores the whole object

I have an array of objects -我有一组对象 -

let initialArr = [
  {
    "id": 1,
    "name": "product name",
    "product_details": [
      {
        "id": 1,
        "details": "some details"
      }
    ],
    "subscriptions": [
      {
        "id": 1,
        "subs": "7 days"
      },
      {
        "id": 2,
        "subs": "15 days"
      }
    ]
  },
  {
    "id": 2,
    "name": "product name 2",
    "product_details": [
      {
        "id": 2,
        "details": "some details 2"
      }
    ],
    "subscriptions": [
      {
        "id": 1,
        "subs": "7 days"
      },
      {
        "id": 2,
        "subs": "15 days"
      }
    ]
  },
  {
    "id": 3,
    "name": "product name 3",
    "product_details": [
      {
        "id": 3,
        "details": "some details 3"
      }
    ],
    "subscriptions": []
  }
]

This is what I want to achieve -这就是我想要实现的-

[
  {
    "id": 1,
    "name": "product name",
    "detailsId" : 1,
    "details": "some details"
    "subsId": 1,
    "subs": "7 days"
  },
  {
    "id": 1,
    "name": "product name",
    "detailsId" : 1,
    "details": "some details"
    "subsId": 2,
    "subs": "15 days"
  },
  {
    "id": 2,
    "name": "product name 2",
    "detailsId" : 2,
    "details": "some details 2"
    "subsId": 1,
    "subs": "7 days"
  },
  {
    "id": 2,
    "name": "product name 2",
    "detailsId" : 2,
    "details": "some details 2"
    "subsId": 2,
    "subs": "15 days"
  },
  {
    "id": 3,
    "name": "product name 3",
    "detailsId" : 3,
    "details": "some details 3"
  }
]

This is what I have done -这就是我所做的-

initialArr.map(e => {
  e.product_details.map(p =>{
   e.subscriptions.map(s => {
      newArr.push({
        id: e.id,
        name: e.name,
        detailsId: p.id,
        details: p.details,
        subsId: s.id,
        subs:s.subs        
      }); 
   }); 
  })
})

This works if subscriptions array is not empty.如果 subscriptions 数组不为空,则此方法有效。 If for some product, subscriptions array is empty, then that product is not pushed into the array.如果对于某些产品, subscriptions 数组为空,则不会将该产品推送到该数组中。 In I am unable to figure out how to solve it.在我无法弄清楚如何解决它。

3rd product is not pushed in the new array.第三个产品未推送到新阵列中。 This is what I get -这就是我得到的 -

[
  {
    "id": 1,
    "name": "product name",
    "detailsId" : 1,
    "details": "some details"
    "subsId": 1,
    "subs": "7 days"
  },
  {
    "id": 1,
    "name": "product name",
    "detailsId" : 1,
    "details": "some details"
    "subsId": 2,
    "subs": "15 days"
  },
  {
    "id": 2,
    "name": "product name 2",
    "detailsId" : 2,
    "details": "some details 2"
    "subsId": 1,
    "subs": "7 days"
  },
  {
    "id": 2,
    "name": "product name 2",
    "detailsId" : 2,
    "details": "some details 2"
    "subsId": 2,
    "subs": "15 days"
  }
]

Note: Although the same product is repeated twice in the new array, but this is the requirement - products according to "subs" property of subscriptions array.注意:虽然相同的产品在新数组中重复了两次,但这是需求 - 产品根据订阅数组的“subs”属性。

Supposing i had more arrays eg 'Customizations', 'Orders', etc. besides 'Subscriptions' and i want those arrays' data also to be pushed, is this the correct way to do for multiple arrays?假设除了“订阅”之外,我还有更多的数组,例如“自定义”、“订单”等,并且我希望这些数组的数据也被推送,这是处理多个数组的正确方法吗?

Assuming array product_details has allways 1 element with it's data this is a sollution.假设数组 product_details 总是有 1 个元素和它的数据,这是一个解决方案。
Using Array#reduce to accumulate your new result-array.使用Array#reduce来累积新的结果数组。 Creating foreach element a new temp-object with the data for all of it.为每个元素创建一个新的临时对象,其中包含所有元素的数据。 If the subscriptions-array is empty push this temp-object to your accumulated result-array.如果订阅数组为空,则将此临时对象推送到您累积的结果数组。 Otherwise use Array#forEach to iterate over your subscriptions.否则使用Array#forEach迭代您的订阅。 For every subscription use Object.assign to make a copy of your temp-object.对于每个订阅,请使用Object.assign制作临时对象的副本。 Add to this the subscription-data and push it to the result-array.添加订阅数据并将其推送到结果数组。

 const initialArr = [{ id: 1, name: "product name", product_details: [{ id: 1, details: "some details" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 2, name: "product name 2", product_details: [{ id: 2, details: "some details 2" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 3, name: "product name 3", product_details: [{ id: 3, details: "some details 3" }], subscriptions: [] }]; let res = initialArr.reduce((acc, cur) => { let temp = { id: cur.id, name: cur.name, detailsId: cur.product_details[0].id, details: cur.product_details[0].details } if (!cur.subscriptions.length) acc.push(temp); else { cur.subscriptions.forEach(subs => { let tempSub = Object.assign({}, temp); tempSub.subsId = subs.id; tempSub.subs = subs.subs; acc.push(tempSub); }) } return acc; }, []); console.log(res);

Here a version without reduce and instead forEach :这是一个没有reduce而是forEach的版本:

 const initialArr = [{ id: 1, name: "product name", product_details: [{ id: 1, details: "some details" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 2, name: "product name 2", product_details: [{ id: 2, details: "some details 2" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 3, name: "product name 3", product_details: [{ id: 3, details: "some details 3" }], subscriptions: [] }]; let acc = []; initialArr.forEach(cur => { let temp = { id: cur.id, name: cur.name, detailsId: cur.product_details[0].id, details: cur.product_details[0].details } if (!cur.subscriptions.length) acc.push(temp); else { cur.subscriptions.forEach(subs => { let tempSub = Object.assign({}, temp); tempSub.subsId = subs.id; tempSub.subs = subs.subs; acc.push(tempSub); }) } }); console.log(acc);

You could check the length of subscription and return an object instead of mapping the array.您可以检查subscription的长度并返回一个对象而不是映射数组。

 const data = [{ id: 1, name: "product name", product_details: [{ id: 1, details: "some details" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 2, name: "product name 2", product_details: [{ id: 2, details: "some details 2" }], subscriptions: [{ id: 1, subs: "7 days" }, { id: 2, subs: "15 days" }] }, { id: 3, name: "product name 3", product_details: [{ id: 3, details: "some details 3" }], subscriptions: [] }], result = data.flatMap(({ product_details: [{ id: detailsId, details }], subscriptions, ...o }) => subscriptions.length ? subscriptions.map(({ id: subsId, subs }) => ({ ...o, detailsId, details, subsId, subs })) : ({ ...o, detailsId, details }) ); console.log(result);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

you need to deal with the case explicitly:你需要明确地处理这个案例:

if (e.subscriptions.length === 0) {
  newArr.push({ ... }
} else {
  e.subscriptions.map(...)
}

also you should use forEach instead of map .你也应该使用forEach而不是map

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM