-2

I have been working on a Cartesian product with a below array of objects.

[
    {
        "name": "Size",
        "values": ["10", "39"]
    },
    {
        "name": "Color",
        "values": ["Yellow", "Pink"]
    },
    {
        "name": "Country",
        "values": ["USA", "UK"]
    }
]

And I want to generate a cartesian product of the properties so that the output is an array of the following form:

[
    [
      { id: 1, name: 'Size', value: '10' },
      { id: 2, name: 'Color', value: 'Yellow' },
      { id: 3, name: 'Country', value: 'USA' },
    ],
    [
      { id: 1, name: 'Size', value: '10' },
      { id: 2, name: 'Color', value: 'Yellow' },
      { id: 3, name: 'Country', value: 'UK' },
    ],
    [
      { id: 1, name: 'Size', value: '39' },
      { id: 2, name: 'Color', value: 'Yellow' },
      { id: 3, name: 'Country', value: 'USA' },
    ],
    [
      { id: 1, name: 'Size', value: '39' },
      { id: 2, name: 'Color', value: 'Yellow' },
      { id: 3, name: 'Country', value: 'UK' },
    ],
    [
      { id: 1, name: 'Size', value: '10' },
      { id: 2, name: 'Color', value: 'Pink' },
      { id: 3, name: 'Country', value: 'USA' },
    ],
    [
      { id: 1, name: 'Size', value: '10' },
      { id: 2, name: 'Color', value: 'Pink' },
      { id: 3, name: 'Country', value: 'UK' },
    ],
    [
      { id: 1, name: 'Size', value: '39' },
      { id: 2, name: 'Color', value: 'Pink' },
      { id: 3, name: 'Country', value: 'USA' },
    ],  
    [ 
      { id: 1, name: 'Size', value: '39' },
      { id: 2, name: 'Color', value: 'Pink' },
      { id: 3, name: 'Country', value: 'UK' },
    ],  
  ];
James Z
  • 12,209
  • 10
  • 24
  • 44
dacoten
  • 115
  • 2
  • 12
  • 1
    [Use object array to generate a new array dynamically](https://stackoverflow.com/questions/59560911) – adiga May 02 '23 at 08:37

2 Answers2

1

Here's one concise way to do this with recursion:

const f = (xs, i = 1) =>
  xs.length === 0
    ? [[]]
    : f(xs.slice(1), i + 1).flatMap(y =>
        xs[0].values.map(value => [{ id: i, name: xs[0].name, value }, ...y]),
      )

console.log(
  f([
    {
      name: 'Size',
      values: ['10', '39'],
    },
    {
      name: 'Color',
      values: ['Yellow', 'Pink'],
    },
    {
      name: 'Country',
      values: ['USA', 'UK'],
    },
  ]),
)

Output:

[
  [
    { id: 1, name: 'Size', value: '10' },
    { id: 2, name: 'Color', value: 'Yellow' },
    { id: 3, name: 'Country', value: 'USA' }
  ],
  [
    { id: 1, name: 'Size', value: '39' },
    { id: 2, name: 'Color', value: 'Yellow' },
    { id: 3, name: 'Country', value: 'USA' }
  ],
  [
    { id: 1, name: 'Size', value: '10' },
    { id: 2, name: 'Color', value: 'Pink' },
    { id: 3, name: 'Country', value: 'USA' }
  ],
  [
    { id: 1, name: 'Size', value: '39' },
    { id: 2, name: 'Color', value: 'Pink' },
    { id: 3, name: 'Country', value: 'USA' }
  ],
  [
    { id: 1, name: 'Size', value: '10' },
    { id: 2, name: 'Color', value: 'Yellow' },
    { id: 3, name: 'Country', value: 'UK' }
  ],
  [
    { id: 1, name: 'Size', value: '39' },
    { id: 2, name: 'Color', value: 'Yellow' },
    { id: 3, name: 'Country', value: 'UK' }
  ],
  [
    { id: 1, name: 'Size', value: '10' },
    { id: 2, name: 'Color', value: 'Pink' },
    { id: 3, name: 'Country', value: 'UK' }
  ],
  [
    { id: 1, name: 'Size', value: '39' },
    { id: 2, name: 'Color', value: 'Pink' },
    { id: 3, name: 'Country', value: 'UK' }
  ]
]
Dogbert
  • 212,659
  • 41
  • 396
  • 397
1

here is a non-recursive solution based on a previous answer

const data = [
    {
        "name": "Size",
        "values": ["10", "39"]
    },
    {
        "name": "Color",
        "values": ["Yellow", "Pink"]
    },
    {
        "name": "Country",
        "values": ["USA", "UK"]
    }
]


const combined = data.reduce((a,{name,values},i)=>{
    return a.flatMap(x => values.map(y=> x.concat({ id:i+1, name, value:y })))
},[[]])
 
 console.log(JSON.parse(JSON.stringify(combined)))
cmgchess
  • 7,996
  • 37
  • 44
  • 62