简体   繁体   English

Node Js - 展平对象数组

[英]Node Js - Flatten array of objects

I have an array like this我有一个这样的数组

var data = [
    {
        family: "Fam A",
        category: "Cat A",
        products: [
            {
                name: "Name A1",
                style: "Style A1"
            },
            {
                name: "Name A2",
                style: "Style A2"
            }
        ]
    },
    {
        family: "Fam B",
        category: "Cat B",
        products: [
            {
                name: "Name B1",
                style: "Style B1"
            },
            {
                name: "Name B2",
                style: "Style B2"
            }
        ]
    }
]; 

I want to change the inside objects like below我想改变像下面这样的内部对象

var data = [
    {family:"Fam A", category: "Cat A", name: "Name A1", style:"Style A1"},
    {family:"Fam A", category: "Cat A", name: "Name A2", style:"Style A2"},
    {family:"Fam B", category: "Cat B", name: "Name B1", style:"Style B1"},
    {family:"Fam B", category: "Cat B", name: "Name B2", style:"Style B2"}
]  

I've tried using map and forEach that I found in other posts but haven't gotten anything to work.我尝试使用在其他帖子中找到的 map 和 forEach,但没有任何效果。

var flattened = data.products.map(x => Object.assign(x, { productDetails: data.products }))

function getList(data, arrayKey, arrayName) {
    data[arrayKey].forEach(function(element) {
        element[arrayName] = data[arrayName];
    });
    return data[arrayKey];
}

The ideal solution would be able to handle dynamic no of nestings but not necessary to move on.理想的解决方案将能够处理动态没有嵌套但没有必要继续前进。

Thank you in advance for helping a newer dev!提前感谢您帮助新开发人员!

You could take Array#flatMap with a nested mapping.您可以将Array#flatMap与嵌套映射一起使用。

 var data = [{ family: "Fam A", category: "Cat A", products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }] }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }], flat = data.flatMap(({ products, ...o }) => products.map(p => ({ ...o, ...p }))); console.log(flat);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

I can offer the general (recursive) solution: 我可以提供一般(递归)解决方案:

 var data = [ { family: "Fam A", category: "Cat A", products: { somekey: 'someval', items : { type: 'A type', list: [{name: "Name A1", style: "Style A1"}, {name: "Name A2", style: "Style A2"}] } } }, { family: "Fam B", category: "Cat B", products: { somekey: 'someval', items :[{name: "Name B1", style: "Style B1"}, {name: "Name B2", style: "Style B2"}] } } ]; const output = data.reduce((aggArr, child) => { function recursiveFlat(currChild, currParent){ currParent = currParent || {}; return Object.entries(currChild).reduce((aggChildArr,[key,val]) => { let tempObj = {...currParent, ...currChild} if (val instanceof Array){ delete tempObj[key]; val.forEach(item => { aggChildArr.push({...tempObj,...item}); }) }else if(val instanceof Object){ delete tempObj[key]; aggChildArr = [...aggChildArr, ...recursiveFlat(val, tempObj)]; } return aggChildArr; },[]) } const flatArr = recursiveFlat(child); flatArr.forEach(item => aggArr.push(item)); return aggArr; },[]) console.log(output);
 .as-console-wrapper { max-height: 100% !important; top: 0; }

update , trying to take the beautiful .flatMap() solution and make it generic & recursive: update ,尝试采用漂亮的.flatMap()解决方案并使其通用和递归:

 const data = [{ family: "Fam A", category: "Cat A", items: { types: {type: 'A1-2', products: [{ name: "Name A1", style: "Style A1" }, { name: "Name A2", style: "Style A2" }]}, somekey: 'example' } }, { family: "Fam B", category: "Cat B", products: [{ name: "Name B1", style: "Style B1" }, { name: "Name B2", style: "Style B2" }] }]; function flatten(data){ const flat = data.flatMap((obj) => { function innerFlatten(obj, parentObj){ parentObj = parentObj || {}; for (key in obj){ if (obj[key] instanceof Array){ const tempArr = obj[key]; delete obj[key]; return tempArr.map(p => ({...parentObj, ...obj, ...p }) ) }else if (obj[key] instanceof Object){ const tempObj = obj[key]; delete obj[key]; return innerFlatten(tempObj, {...parentObj, ...obj}); } } } return innerFlatten(obj); }); return flat; } console.log(flatten(data));
 .as-console-wrapper { max-height: 100% !important; top: 0; }

You can use reduce , faster and better.您可以使用reduce ,更快更好。

 var data = [{"family":"Fam A","category":"Cat A","products":[{"name":"Name A1","style":"Style A1"},{"name":"Name A2","style":"Style A2"}]},{"family":"Fam B","category":"Cat B","products":[{"name":"Name B1","style":"Style B1"},{"name":"Name B2","style":"Style B2"}]}]; const result = data.reduce( (map, { products, ...rest }) => map.concat(products.map(product => ({ ...rest, ...product }))), [] ); console.log(result);

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

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