Thalapathy
Thalapathy

Reputation: 147

Combination of all possible values from first array?

How do a combine the array of arrays based on the first array1 or basically group by array1.

Below is the four Array, where i have to form objects based on A and then based on B.

var array1=["A","B"];
var array2=["1","2","3", "4"];
var array3=["N","O","P", "Q"];
var array4=["R"];

Below is how i need :

[ {
  'take': 'A', 
  'take2': '1',
  'take3': 'N',
  'take4': 'R'
}, {
  'take': 'A', 
  'take2': '2',
  'take3': 'N',
  'take4': 'R'
}, {
  'take': 'A', 
  'take2': '3',
  'take3': 'N',
  'take4': 'R'
}, {
  'take': 'A', 
  'take2': '4',
  'take3': 'N',
  'take4': 'R'
}, {
  'take': 'A', 
  'take2': '1',
  'take3': 'O',
  'take4': 'R'
}]

This is something i have tried, but not sure how can i loop n number of n arrays

var result = array1.reduce( (a, v) =>
   [...a, ...array2.map(x=>v+x)],
[]);

Upvotes: 0

Views: 78

Answers (3)

guijob
guijob

Reputation: 4488

Here's a recursive approach which works for every number of arrays, you just have to call combine(array1, array2, ..., arrayn):

var array1=["A","B"];
var array2=["1","2","3", "4"];
var array3=["N","O","P", "Q"];
var array4=["R"];

function combine(arr1, ...arr2) {
  if(arr2.length === 0) return Array.from(arr1, (x) => x.reduce((obj, y, i) => (obj[`take${i}`] = y, obj), {}));
  
  return combine(arr1.flatMap(d => arr2[0].map(v => {
  return [...Object.values(d), ...Object.values(v)]
  })), ...arr2.slice(1));
}

console.log(combine(array1, array2, array3, array4));

Upvotes: 1

Thomas
Thomas

Reputation: 12677

I've written a function for this task a while ago, takes an arbitrary amount of Arrays and non-arrays and computes all possible combinations

var array1 = ["A", "B"];
var array2 = ["1", "2", "3", "4"];
var array3 = ["N", "O", "P", "Q"];
var array4 = ["R"];

console.log(combinations(array1, array2, array3, array4).join("\n"));

function combinations(...columns) {
  const state = [], combinations = [state];
  let head = null;
  for (let column = 0; column < columns.length; ++column) {
    let value = columns[column];
    if (Array.isArray(value)) {
      if (value.length > 1) {
        head = {
          next: head,
          column,
          row: 0
        };
      }
      value = value[0];
    }
    state[column] = value;
  }

  let todo = head;
  while(todo) {
    if (++todo.row === columns[todo.column].length) {
      todo.row = 0;
      state[todo.column] = columns[todo.column][todo.row];
      todo = todo.next;
    } else {
      state[todo.column] = columns[todo.column][todo.row];
      combinations.push(state.slice());
      todo = head;
    }
  }

  return combinations;
}
.as-console-wrapper{top:0;max-height:100%!important}

Upvotes: 1

Antoine Gautrain
Antoine Gautrain

Reputation: 421

here is a keep it simple solution (if you know how many arrays do you have) :

const possibilities = [];

const ar1length = array1.length;
const ar2length = array2.length;
const ar3length = array3.length;
const ar4length = array4.length;

// Not cleanest solution available but it does the job

for ( let i = 0; i < ar1length; i++) {

    for (let j = 0; j < ar2length; j++) {

        for (let k = 0; k < ar3length; k++) {

            for (let l = 0; l < ar4length; l++) {

                possibilities.push({
                    "take": array1[i],
                    "take1": array2[j],
                    "take2": array3[k],
                    "take3": array4[l]
                });


            }


        }

    }
}

Oh and if you want an unknown number of arrays, you may add all of these arrays to an array in order to iterate over it I guess

Upvotes: 3

Related Questions