Search code examples
javascriptarraysobjectjavascript-objects

How can I create several arrays on each of the values of other array of objects?


So currently I have this array structure:

const object = {
  object1: ["01", "02"],
  object2: ["item1", "item2", "item3"],
  object3: ["product1", "product2"]
}

and I need to transform it to:

const array = [
  {
    object1: "01",
    object2: "item1",
    object3: "product1",
  }, {
    object1: "02",
    object2: "item1",
    object3: "product1",
  }, {
    object1: "01",
    object2: "item2",
    object3: "product1",
  }, {
    object1: "01",
    object2: "item3",
    object3: "product1",
  }, {
    object1: "02",
    object2: "item2",
    object3: "product1",
  }, {
    object1: "02",
    object2: "item3",
    object3: "product1",
  }, {
    object1: "01",
    object2: "item1",
    object3: "product2",
  }, {
    object1: "02",
    object2: "item1",
    object3: "product2",
  }, {
    object1: "02",
    object2: "item2",
    object3: "product2",
  }, {
    object1: "03",
    object2: "item2",
    object3: "product2",
  },
]

So basically I need to create a new array based off of each combination on the initial object of arrays, and the initial array the be on the thousands of items.

This is what I have so far but no luck getting the structure I need.

const object = {
  object1: ["01", "02"],
  object2: ["item1", "item2", "item3"],
  object3: ["product1", "product2"]
}
const arr = []
Object.entries(object).forEach((element, i) => {
  element.forEach((innerElement, j) => {
    let _element = {[`${element[0]}`]:element[1][j]}
    arr.push(_element)
  })
});

console.log("map", arr)

Is there any way to transform the data to the structure I need it? Thanks in advance!


Solution

  • I'd suggest creating a generic solution that will iterate over the possible properties and values of the template object and create an array of all possible outcomes.

    We'd create a addPossibleValues() function than will expand the array of objects for each key in the template object. Each round will increase the number of objects by the successive length of the relevant property array.

    const object = {
      object1: ["01", "02"],
      object2: ["item1", "item2", "item3"],
      object3: ["product1", "product2"]
    }
    
    function addPossibleValues(arr, property, possibleValues) {
        return possibleValues.flatMap(v => { 
            return (arr.length ? arr: [{}]).map(x => { 
                return { ...x, [property]: v};
            })
        });
    }
    
    let result = [];
    for(let key in object) {
        result = addPossibleValues(result, key, object[key]);
    }
    
    console.log('Result:', result)
    .as-console-wrapper { max-height: 100% !important; }

    You could also do this using a Array.reduce() call:

    const object = {
      object1: ["01", "02"],
      object2: ["item1", "item2", "item3"],
      object3: ["product1", "product2"]
    }
    
    function addPossibleValues(arr, property, possibleValues) {
        return possibleValues.flatMap(v => { 
            return (arr.length ? arr: [{}]).map(x => { 
                return { ...x, [property]: v};
            })
        });
    }
    
    let result = Object.keys(object).reduce((acc, key) => {
        return addPossibleValues(acc, key, object[key]);
    }, []);
    console.log('Result:', result)
    .as-console-wrapper { max-height: 100% !important; }