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

Javascript 将包含空数组的对象数组映射为属性会忽略整个对象,javascript,arrays,json,object,Javascript,Arrays,Json,Object,我有一个对象数组- let initialArr = [ { "id": 1, "name": "product name", "product_details": [ { "id": 1, "details": "some details" } ], &qu

我有一个对象数组-

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": []
  }
]
这就是我想要实现的目标-

[
  {
    "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"
  }
]

这就是我所做的-

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        
      }); 
   }); 
  })
})

如果订阅数组不为空,则此操作有效。如果对于某些产品,订阅数组为空,则不会将该产品推送到数组中。实际上,我想不出如何解决这个问题

新阵列中未推出第三个产品。这就是我得到的-

[
  {
    "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"
  }
]

注意:虽然同一产品在新数组中重复两次,但这是根据订阅数组的“subs”属性的要求-产品


假设我有更多的数组,例如“定制”、“订单”等。除了“订阅”之外,我还希望推送这些数组的数据,这是多个数组的正确方法吗?

您需要明确处理这种情况:

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

您还应该使用而不是。

您可以检查
订阅的长度
并返回一个对象,而不是映射数组

const
数据=[{id:1,名称:“产品名称”,产品详细信息:[{id:1,详细信息:“一些详细信息”}],订阅:[{id:1,订阅:“7天”},{id:2,订阅:“15天”},{id:2,名称:“产品名称2”,产品详细信息:[{id:2,详细信息:“一些详细信息2”],订阅:[{id:1,订阅:“7天”},{id:2,订阅:“15天”},{id:3,名称:“产品名称3”,产品详细信息:[{id:3,详细信息:“某些详细信息3”}],订阅:[]},
结果=data.flatMap({product_details:[{id:detailsId,details}],订阅,…o})=>subscriptions.length
?subscriptions.map({id:subsId,subs})=>({…o,detailsId,details,subsId,subs}))
:({…o,detailsId,details})
);
console.log(结果);

.as console wrapper{max height:100%!important;top:0;}
假设数组产品\u details的数据中始终有1个元素,这是一个解决方案。
用于累积新的结果数组。正在为foreach元素创建一个新的临时对象,其中包含所有元素的数据。如果订阅数组为空,则将此临时对象推送到累积结果数组。否则,使用来迭代订阅。对于每个订阅,使用来制作临时对象的副本。将订阅添加到此临时对象并将其推送到结果数组

const initialArr=[{id:1,name:“product name”,product_详细信息:[{id:1,details:“some details”}],订阅:[{id:1,subs:“7天”},{id:2,subs:“15天”},{id:2,name:“product name 2”,product_详细信息:[{id:2,details:“some details 2”}],订阅:[{id:1,subs:“7天”},{id:2,subs:“15天”}],{id:3,名称:“产品名称3”,产品详细信息:[{id:3,详细信息:“某些详细信息3”}],订阅:[]};
让res=初始到达减少((acc,cur)=>{
设温度={
id:cur.id,
姓名:cur.name,
detailsId:cur.product\u详细信息[0]。id,
详细信息:当前产品详细信息[0]。详细信息
}
如果(!cur.subscriptions.length)
附件推送(温度);
否则{
cur.subscriptions.forEach(subs=>{
设tempSub=Object.assign({},temp);
tempSub.subfid=subs.id;
tempSub.subs=subs.subs;
acc.push(tempSub);
})
}
返回acc;
}, []);

console.log(res);
如果没有
返回映射,就不会返回任何数组(…
在bock声明中。在
产品详细信息
中您是否始终只有一个产品?产品详细信息包含产品的详细信息,即产品“产品名称”。因此它始终有一个产品详细信息。我不理解您的第一条评论谢谢。是否可以不使用reduce进行此操作?是的,我添加了它下面是我文章末尾的另一个解决方案。我很高兴能帮助你。顺便说一句,你现在已经有足够的声誉,你可以对答案+问题进行投票,而不仅仅是接受它们。我已经投票了,但它没有注册。再做一次。是的,它与
map
一起工作,但这不是用这种方式使用map的目的,因为map用由内部计算生成的起始数组。此处不使用此值(内部不存在任何返回值),因此结果数组由3个未定义的值组成。注意:如果有一个由n个元素组成的数组,并且结果由相同长度的数组组成,则通常最好使用Map。