Поиск всех комбинаций значений массива JavaScript - PullRequest
51 голосов
/ 02 декабря 2010

Как мне получить все комбинации значений в N количестве массивов JavaScript переменной длины?

Допустим, у меня есть N ряд массивов JavaScript, например,

var first = ['a', 'b', 'c', 'd'];
var second = ['e'];
var third =  ['f', 'g', 'h', 'i', 'j'];

(Три массива в этом примере, но это N количество массивов для задачи.)

И я хочу вывести все комбинации их значений, чтобы получить

aef
aeg
aeh
aei
aej
bef
beg
....
dej

РЕДАКТИРОВАТЬ: Вот версия, которую я получил работать, используя принятый ответ друга в качестве основы.

var allArrays = [['a', 'b'], ['c', 'z'], ['d', 'e', 'f']];

 function allPossibleCases(arr) {
  if (arr.length === 0) {
    return [];
  } 
else if (arr.length ===1){
return arr[0];
}
else {
    var result = [];
    var allCasesOfRest = allPossibleCases(arr.slice(1));  // recur with the rest of array
    for (var c in allCasesOfRest) {
      for (var i = 0; i < arr[0].length; i++) {
        result.push(arr[0][i] + allCasesOfRest[c]);
      }
    }
    return result;
  }

}
var r=allPossibleCases(allArrays);
 //outputs ["acd", "bcd", "azd", "bzd", "ace", "bce", "aze", "bze", "acf", "bcf", "azf", "bzf"]

Ответы [ 12 ]

0 голосов
/ 13 августа 2018

Вы также можете использовать эту функцию:

const result = (arrayOfArrays) => arrayOfArrays.reduce((t, i) => { let ac = []; for (const ti of t) { for (const ii of i) { ac.push(ti + '/' + ii) } } return ac })

result([['a', 'b', 'c', 'd'], ['e'], ['f', 'g', 'h', 'i', 'j']])
// which will output [ 'a/e/f', 'a/e/g', 'a/e/h','a/e/i','a/e/j','b/e/f','b/e/g','b/e/h','b/e/i','b/e/j','c/e/f','c/e/g','c/e/h','c/e/i','c/e/j','d/e/f','d/e/g','d/e/h','d/e/i','d/e/j']

Конечно, вы можете удалить + '/' в ac.push(ti + '/' + ii), чтобы исключить косую черту из конечного результата.И вы можете заменить эти for (... of ...) на функции forEach (плюс соответствующую точку с запятой перед return ac), независимо от того, с кем вам удобнее.

0 голосов
/ 24 февраля 2018

Вот версия, адаптированная из приведенной выше пары ответов, которая производит результаты в порядке, указанном в OP, и возвращает строки вместо массивов:

function *cartesianProduct(...arrays) {
  if (!arrays.length) yield [];
  else {
    const [tail, ...head] = arrays.reverse();
    const beginning = cartesianProduct(...head.reverse());
    for (let b of beginning) for (let t of tail) yield b + t;
  }
}

const first = ['a', 'b', 'c', 'd'];
const second = ['e'];
const third =  ['f', 'g', 'h', 'i', 'j'];
console.log([...cartesianProduct(first, second, third)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...