1

I found this excellent code which generates all the combinations of multiple arrays here: JavaScript - Generating combinations from n arrays with m elements

I am now looking to go a step further and I would like to generate all the combinations of a number of JSON objects containing arrays

For example if I have the two objects within an array seen below:

[{"Footprint_Shape":["L-Shape","H-Shape","T-Shape"]},
{"Num_of_Floors":[1,2]}]

I would like to produce the array below which is every combination while keeping the keys:

    [{"Footprint_Shape": "L-Shape", "Num_of_Floors":1 },
    { "Footprint_Shape": "H-Shape", "Num_of_Floors":1 },
    { "Footprint_Shape": "T-Shape", "Num_of_Floors":1 },
    { "Footprint_Shape": "L-Shape", "Num_of_Floors":2 },
    { "Footprint_Shape": "H-Shape", "Num_of_Floors":2 },
    { "Footprint_Shape": "T-Shape", "Num_of_Floors":2 }]

Please remember that I need to generate all keys and values dynamically.

Any pointers or code samples which would point me in the right direction to write this code would be most appreciated

Anton James
  • 385
  • 3
  • 6
  • 18

3 Answers3

1

You can convert the array of objects into multi dimensional array. Construct possible combinations and use map to construct the final format.

var arr = [{"Footprint_Shape": ["L-Shape", "H-Shape", "T-Shape"]}, {"Num_of_Floors": [1, 2]}];

var result = arr.map(o => Object.values(o)[0])                               //Convert the array of objects into multi dimensional array.
  .reduce((c, v) => [].concat(...c.map(o => v.map(x => [].concat(o, x)))))   //Make all possible combinations
  .map(([a, b]) => ({"Footprint_Shape": a,"Num_of_Floors": b}))              //Construct the final format

console.log(result);

Update:

var arr = [{"Footprint_Shape": ["L-Shape", "H-Shape", "T-Shape"]}, {"Num_of_Floors": [1, 2]}];

var keys = arr.map(o => Object.keys(o)[0]); //Get the list of keys
var result = arr.map(o => Object.values(o)[0]) //Convert the array of objects into multi dimensional array.
  .reduce((c, v) => [].concat(...c.map(o => v.map(x => [].concat(o, x))))) //Make all possible combinations
  .map(o => o.reduce((c, v, i) => Object.assign(c, {[keys[i]]: v}), {})); //Construct the final format

console.log(result);
Eddie
  • 26,593
  • 6
  • 36
  • 58
  • thank you for your answer however I need to be able to do this dynamically e.g - I dont know the number of objects the length of their arrays or the key names within each object ahead of time – Anton James Jun 20 '18 at 14:05
  • @AntonJames Please check the updated code. This is dynamic. – Eddie Jun 20 '18 at 14:15
1

A simple and short alternative:

const [{Footprint_Shape: shapes},{Num_of_Floors: floors} ] = [{"Footprint_Shape":["L-Shape","H-Shape","T-Shape"]},{"Num_of_Floors":[1,2]}];

const result = floors.reduce((all, floor) => {

    shapes.forEach(shape => all.push({Footprint_Shape: shape, Num_of_Floors: floor}))

    return all;

}, []);

console.log(result);
Leonid Pyrlia
  • 1,594
  • 2
  • 11
  • 14
0

let arr = [
  {"Footprint_Shape":["L-Shape","H-Shape","T-Shape"]},
  {"Num_of_Floors":[1,2]}
]

let answer = [];

arr[0]["Footprint_Shape"].forEach(x => {  
  
  arr[1]["Num_of_Floors"].forEach(y => {
    
    let newObj = {};  
    newObj["Footprint_Shape"] = x;
    //console.log('y: ',y)
    newObj["Num_of_Floors"] = y
   answer.push(newObj);
    
  })
});

console.log(answer)

I think the code should be self explanatory. Using two looping, construct the object and push to a new array

Isaac
  • 12,042
  • 16
  • 52
  • 116