0

I see there's too many questions like this , but I did not find answer for my specific case

I need all the possible combinations for my input arrays

example

if we assume the input is [1,2];

the output should be : ["11","12","21","22"]

after research , I reached to this code

function perm(xs) {
  let ret = [];

  for (let i = 0; i < xs.length; i = i + 1) {
    let rest = perm(xs.slice(0, i).concat(xs.slice(i + 1)));

    if(!rest.length) {
      ret.push([xs[i]])
    } else {
      for(let j = 0; j < rest.length; j = j + 1) {
        ret.push([xs[i]].concat(rest[j]).join(""))
      }
    }
  }
  return ret;
}

it finds most of the combinations , but not all

the above code return only ["12","21"] for input [1,2]

however all the possible combinations should be > ["11","12","21","22"]

another example for input [1,2,3] , should have this output

["111","112","121","211","113","131","311","123","321","312","213","132" , "223" , "331" , "313" , "232" .. and so on

4 Answers4

0

If the length of the generated strings should be equal to the size of the input array, then this recursive generator could be used:

function combiWithRepetitions(chars) {
  function * recur(len, str) {
      if (len) for (let chr of chars) yield * recur(len - 1, str + chr);
      else yield str;
  }
  return [...recur(chars.length, "")];
}  

let result = combiWithRepetitions([1, 2]);

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286
0

You are looking for permutation with repetitions that are of the same length as the input array. This code (adapted from: https://stackoverflow.com/a/30340475/9560885) gives you the output you want:

function perm(arr) {
  var holdingArr = [];
  var recursiveABC = function(singleSolution) {
      if (singleSolution.length == arr.length) {
        holdingArr.push(singleSolution);
        return;
      }
      for (var i=0; i < arr.length; i++) {
        recursiveABC(singleSolution.concat([arr[i]]).toString());
      }
  };
  recursiveABC([]);
  return holdingArr;
};

Example:

> perm([1,2])
[ '11', '12', '21', '22' ]

Another example:

> perm([1,2])
[ '111',
  '112',
  '113',
  '121',
  '122',
  '123',
  '131',
  '132',
  '133',
  '211',
  '212',
  '213',
  '221',
  '222',
  '223',
  '231',
  '232',
  '233',
  '311',
  '312',
  '313',
  '321',
  '322',
  '323',
  '331',
  '332',
  '333' ]
Luka Kralj
  • 446
  • 3
  • 12
0

You could build a cartesian product of the wanted length with a generato function.

function getP(array, length) {
    function* p(right = []) {
        if (right.length === length) {
            yield right.join('');
            return;
        }
        for (const v of array) yield* p([...right, v])
    }
    return p();
}

console.log([...getP([1, 2, 3], 3)]);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Here's a one liner:

const f = (xs, l=xs.length) => l ? xs.flatMap(x => f(xs, l-1).flatMap(y => x + y)) : [''];

console.log(f([1, 2, 3]));
גלעד ברקן
  • 23,602
  • 3
  • 25
  • 61