如何展平对象的嵌套数组并复制父对象

How to flatten the nested array of of objects and duplicate the parent

我有一个对象数组,其中一个属性 ("attributes") 作为对象数组。

var products = [
    {
        "productId": "1",
        "attributes": [
            {
                "variant":"red",
                "price": "134.00"
            }
        ]
    },
    {
        "productId": "2",
        "attributes": [
            {
                "variant": "green",
                "value": "3400.00"
            },
            {
                "variant": "pink",
                "price": "342.00"
            }
        ]
    }
]

我希望将嵌套对象数组展平并复制到父对象上,但需要为每个嵌套对象复制父对象。 (不确定我是否解释正确)。

转换后的对象数组应该是:

var transformedProducts = [
    {
        "productId": "1",
        "variant":"red",
        "price": "134.00"
    },
    {
        "productId": "2",
        "variant": "green",
        "value": "3400.00"
    },
    {
        "productId": "2",
        "variant": "pink",
        "price": "342.00"
    }
]

我可以映射外部数组,然后再次映射内部数组,并在最里面的映射中构造一个新对象。
对此有更好或更实用的方法吗?

此代码应该适合您:

const transformedProducts = [];

products.forEach((product) => {
    product.attributes.forEach((attribute) => {
        transformedProducts.push({
            productId: product.productId,
            ...attribute,
        });
    });
});

您可以使用Array.flatMap()迭代对象,然后用Array.map()迭代attributes,并与对象的其余部分组合。 Array.flatMap() 还会将数组的数组展平为单个数组。

const fn = arr => arr.flatMap(({ attributes, ...rest }) => 
  attributes.map(o => ({
    ...rest,
    ...o
  }))
)

const products = [{"productId":"1","attributes":[{"variant":"red","price":"134.00"}]},{"productId":"2","attributes":[{"variant":"green","value":"3400.00"},{"variant":"pink","price":"342.00"}]}]

const result = fn(products)

console.log(result)

使用 Ramda,您可以使用 R.chain 迭代和展平数组。要获得与其父属性组合的属性数组,您可以使用 R.ap 作为两个函数的组合器:

  1. 提取属性数组,然后将其应用于第二个函数。
  2. 获取对象的其余部分(没有属性),并创建一个将其合并到迭代对象的映射函数。

const { chain, ap, pipe, prop, applyTo, omit, mergeRight, map } = R

const fn = chain(ap(
  pipe(prop('attributes'), applyTo),
  pipe(omit(['attributes']), mergeRight, map)
))

const products = [{"productId":"1","attributes":[{"variant":"red","price":"134.00"}]},{"productId":"2","attributes":[{"variant":"green","value":"3400.00"},{"variant":"pink","price":"342.00"}]}]

const result = fn(products)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

您可以按如下方式使用Array#map and Array#flat

const products = [ { "productId": "1", "attributes": [ { "variant":"red", "price": "134.00" } ] }, { "productId": "2", "attributes": [ { "variant": "green", "value": "3400.00" }, { "variant": "pink", "price": "342.00" } ] } ];

const output = products.map(({productId,attributes}) => 
    attributes.map(({variant,price}) => ({productId,variant,price}))
)
.flat();

console.log( output );

或者只命名 attributes,以防有其他属性:

const products = [ { "productId": "1", "attributes": [ { "variant":"red", "price": "134.00" } ] }, { "productId": "2", "attributes": [ { "variant": "green", "value": "3400.00" }, { "variant": "pink", "price": "342.00" } ] } ];

const output = products.map(({attributes,...rest}) => 
    attributes.map(attribute => ({...rest,...attribute}))
)
.flat();

console.log( output );