Whiskey T.
Whiskey T.

Reputation: 243

How to transform/map JSON data into different model

I'm trying to wrap my head around how to transform some data. It's an array of objects, with each object containing an array of items, each item being a unique combination of color and size.

[
    {
        "style": "styleName_01",
        "someOtherKey": "",
        "skus": [
            { "sku": "001", "color": "COLOR_01", "size": "SIZE_08" },
            { "sku": "002", "color": "COLOR_02", "size": "SIZE_07" },
            { "sku": "003", "color": "COLOR_02", "size": "SIZE_08" },
            { "sku": "004", "color": "COLOR_02", "size": "SIZE_12" }
        ]
    },
    {
        "style": "styleName_02",
        "someOtherKey": "",
        "skus": [
            { "sku": "005", "color": "COLOR_01", "size": "SIZE_05" },
            { "sku": "006", "color": "COLOR_03", "size": "SIZE_07" },
            { "sku": "007", "color": "COLOR_03", "size": "SIZE_08" },
            { "sku": "008", "color": "COLOR_02", "size": "SIZE_04" }
        ]
    }
]

The product is selected first by color, which filters to sizes available in the color, so I'm trying to get each color that occurs in my skus loop and then find all the items with sizes that occur in that color, i.e.,

[
    {
        "style": "",
        "someOtherKey": "",
        "sku": "001",
        "color": "COLOR_01",
        "sizes": [ "SIZE_08", "SIZE_05" ]
    },
    {
        "style": "",
        "someOtherKey": "",
        "sku": "002",
        "color": "COLOR_02",
        "sizes": [ "SIZE_07", "SIZE_08", "SIZE_12", "SIZE_04"  ]
    },
    {
        "style": "",
        "someOtherKey": "",
        "sku": "003",
        "color": "COLOR_03",
        "sizes": [ "SIZE_07", "SIZE_08" ]
    }
]

I'm able to build the sku objects but I need some guidance as to how to get only the (unique) size values where I need them:

let newSkus = []

let newSku = {
    "sku": "",
    "color": "",
    "sizes": []
}

for (style of data) { // for each style object ...
    let numSkus = style.skus.length;

    for (let sku = numSkus - 1; sku >= 0; sku--) { // for each item in items[]

        if (newSku.color !== `${style.skus[sku].color}`) {
            newSku.color = `${style.skus[sku].color}`;
            newSku.sizes.push(`${style.skus[sku].frameSize}`);
        }
        else {}

        console.log("newSku", newSku); // wrong; getting all sizes from all items

Thanks in advance for suggestions.

Whiskey T.

Upvotes: 0

Views: 179

Answers (1)

A_A
A_A

Reputation: 1932

I would split it up into multiple steps:

  1. create array of all skus (as we don't care to which style name they belong)
  2. group it by color (and join the sizes to a single array)
  3. convert it to your desired format

You can see the output of each step in the console:

const data = [
    {
        "style": "styleName_01",
        "skus": [
            { "sku": "001", "color": "COLOR_01", "size": "SIZE_08" },
            { "sku": "002", "color": "COLOR_02", "size": "SIZE_07" },
            { "sku": "003", "color": "COLOR_02", "size": "SIZE_08" },
            { "sku": "004", "color": "COLOR_02", "size": "SIZE_12" }
        ]
    },
    {
        "style": "styleName_02",
        "skus": [
            { "sku": "005", "color": "COLOR_01", "size": "SIZE_05" },
            { "sku": "006", "color": "COLOR_03", "size": "SIZE_07" },
            { "sku": "007", "color": "COLOR_03", "size": "SIZE_08" },
            { "sku": "008", "color": "COLOR_02", "size": "SIZE_04" }
        ]
    }
]

// flatten into an array of skus
const skus = data.flatMap(style => style.skus)
console.log('skus', skus)

// group by color
const colorsObj = skus.reduce((colors, sku) => {
  if (!colors.hasOwnProperty(sku.color))
    colors[sku.color] = [] // use Set if you want unique values
  colors[sku.color].push(sku.size)
  return colors
}, {})
console.log('colorsObj', colorsObj)

// create array from object entries
const colorsArr = Object.entries(colorsObj).map(([color, sizes], i) => {
  return {
    sku: i,
    color,
    sizes
  }
})
console.log('colorsArr', colorsArr)

Upvotes: 1

Related Questions