JavaScript - Generating combinations from dictiona

2019-07-23 20:03发布

问题:

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

回答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);



回答2:

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);


回答3:

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