Home > Net >  Cartesian product of an unknown amount of arrays/objects WITH label identifiers
Cartesian product of an unknown amount of arrays/objects WITH label identifiers

Time:12-09

Alright, I know that there are a few posts about getting the product of an unknown amount arrays with unknown amount of elements -

JavaScript - Generating combinations from n arrays with m elements

Cartesian array based on array of objects in Javascript

To name a few - However, I have a need for a slight twist -

What I would like is a function that can output an Array of serialized objects instead of an Array of Arrays..

for example, if the input of the function were -

scenarioBuilder({ENV: ["QA","UAT"], HOST: ["APP1", "APP2", "APP3"], API: ["Example1", "Example2"]})

The output would be an array of serialized objects like this -

[{ENV: "QA", HOST: "APP1", API: "Example1"}, 
{ENV: "UAT", HOST: "APP1", API: "Example1"},
{ENV: "QA", HOST: "APP2", API: "Example1"},
{ENV: "UAT", HOST: "APP2", API: "Example1"},
{ENV: "QA", HOST: "APP3", API: "Example1"},
{ENV: "UAT", HOST: "APP3", API: "Example1"}]

etc. etc. etc.

Essentially taking the Array of ENV, HOSTS, AND API's - and making a serialized scenario builder.

I've tried a few cracks at adapting a few of the methods from the above links, but I have had no luck.

specifically -

function cartesian(...args) {
    var r = [], max = args.length-1;
    function helper(arr, i) {
        for (var j=0, l=args[i].length; j<l; j  ) {
            var a = arr.slice(0); // clone arr
            a.push(args[i][j]);
            if (i==max)
                r.push(a);
            else
                helper(a, i 1);
        }
    }
    helper([], 0);
    return r;
}

But Javascript isn't my main language and I honestly have no clue how to break apart the Arrays and reassemble the objects.

Can anyone take a shot at it?

Thank you as always.

CodePudding user response:

this a just a recursive matter...

const data = 
  { ENV : [ 'QA', 'UAT' ] 
  , HOST: [ 'APP1', 'APP2', 'APP3' ] 
  , API : [ 'Example1', 'Example2' ] 
  } 
 
const scenarioBuilder = objXarr =>
  {
  let names = Object.keys( objXarr )
    , len   = names.length -1
    , resp  = []
    ;
  buildIn( {}, 0)
  return resp

  function buildIn(obj, indx)
    {
    let key = names[indx]
    for (let val of objXarr[ key ] )
      {
      let oo = {...obj,[key]:val}
      if (indx < len )  buildIn(oo, indx  1)
      else resp.push( oo )
      }
    }
  }

console.log( scenarioBuilder( data ) )
.as-console-wrapper {max-height: 100%!important;top:0 }

  • Related