Home > Blockchain >  How create array containing all combinations of array 1-n array items?
How create array containing all combinations of array 1-n array items?

Time:02-18

We have the following task, to convert the array below called passengerFlights (object with passenger-id-keys and array of flights) to:

(1) an array with all possible combination of passenger-flights:

EXPECTED OUTPUT:

[
    ["aaa", "ddd", "eee"],
    ["aaa", "ddd", "fff"],
    ["bbb", "ddd", "eee"],
    ["bbb", "ddd", "fff"],
    ["ccc", "ddd", "eee"],
    ["ccc", "ddd", "fff"]
]

and (2) with the stipulation that there can be any number of passengers.

The following is an attempt to solve this first as a static example of three flights, although it's not clear the best way to (1) create the array with all possible combinations, and (2) how to solve the 2-n requirement, we assume recursion of some kind.

const passengerFlights = {
    777: [
        {
            _id: "aaa"
        },
        {
            _id: "bbb"
        },
        {
            _id: "ccc"
        }
    ],
    888: [
        {
            _id: "ddd"
        }
    ],
    999: [
        {
            _id: "eee"
        },
        {
            _id: "fff"
        }
    ],
};

const getGroupedFlights = (passengerFlights) => {

    let indexPointer = 0;
    const indexCounters = [0, 0, 0];
    const arr = [];
    while (indexCounters[0] <= passengerFlights['777'].length - 1 || indexCounters[1] <= passengerFlights['888'].length - 1 || indexCounters[2] <= passengerFlights['999'].length - 1) {
        arr.push([passengerFlights['777'][0]._id, passengerFlights['888'][0]._id, passengerFlights['999'][0]._id]);

        if (indexCounters[2] < passengerFlights['999'].length) indexCounters[2]  ;
        if (indexCounters[2] >= passengerFlights['999'].length - 1 && indexCounters[1] < passengerFlights['888'].length) indexCounters[1]  ;
        if (indexCounters[1] >= passengerFlights['888'].length - 1 && indexCounters[0] < passengerFlights['777'].length) indexCounters[0]  ;

        console.log(indexCounters, passengerFlights['888'].length - 1);
    }
    return arr;
}

const groupedFlights = getGroupedFlights(passengerFlights);
console.log(groupedFlights);

CodePudding user response:

It's just a simple recursive problem....

const
  passengerFlights = 
    { 777: [ { _id: 'aaa' } , { _id: 'bbb' } , { _id: 'ccc' } ] 
    , 888: [ { _id: 'ddd' }                                   ] 
    , 999: [ { _id: 'eee' } , { _id: 'fff' }                  ] 
    } 
, result = combinations( passengerFlights, '_id' )
    ;

console.log( result )

function combinations( obj, KeyName )
  {
  let 
    result = []
  , keys   = Object.keys(obj)  // [ "777", "888", "999" ]
  , max    = keys.length -1  
    ;
  f_recursif_combi(0)
  return result

  function f_recursif_combi( level, arr = [] )
    {
    obj[ keys[level] ]    // like :passengerFlights['777']
    .forEach( elm =>      
      {
      let arr2 = [...arr, elm[KeyName] ]; // arr   elm['_id']
      (level < max)
        ? f_recursif_combi(level  1, arr2 )
        : result.push( arr2 )
      })
    }
  }
.as-console-wrapper {max-height: 100%!important;top:0 }

CodePudding user response:

I think it's the Cartesian product of flights sets. So this should help: Cartesian product of multiple arrays in JavaScript

  • Related