Как получить все комбинации значений в двумерном массиве с циклами, беря одно значение из всей строки каждый раз? - PullRequest
1 голос
/ 19 мая 2019

2D-массив, с которым я имею дело, может иметь разную длину в каждой строке, например:

var a = [1, 2, 3];
var b = ["orange", "poke"];
var c = ["melon", "table", 93, 71, "rock"];
var arrayA = [a, b, c];

И я хочу получить все комбинации значений из массива следующим образом:

var result = [arrayA[0][0], arrayA[1][0], arrayA[2][0]];
//some operation with result
result = [arrayA[0][0], arrayA[1][0], arrayA[2][1]];
//some operation with result
result = [arrayA[0][0], arrayA[1][0], arrayA[2][2]];
//some operation with result
.
.
.
.
.
.
result = [arrayA[0][2], arrayA[1][1], arrayA[2][4]];
//some operation with result

Возможно ли достичь этого с помощью циклов при работе с 2D-массивами различной длины из в javascript? Если нет, есть ли другой способ сделать это? Thx

Ответы [ 2 ]

2 голосов
/ 19 мая 2019

Если вы хотите получить каждую комбинацию и сделать что-то с каждой из них, хороший способ справиться с этим - использовать генератор . Это позволяет избежать создания потенциально большого списка в памяти, при этом оставаясь удобным для циклического перебора каждой комбинации. Например:

var a = [1, 2, 3];
var b = ["orange", "poke"];
var c = ["melon", "table", 93, 71, "rock"];
var arrayA = [a, b, c];

function* productGen(arr, cur = []){
  if (arr.length < 1) yield cur
  else {
    for (let item of arr[0]) {
      yield* productGen(arr.slice(1), [...cur, item])
    }
  }
}

for (let combo of productGen(arrayA)){
  // do something with combo
  console.log(combo)
}
0 голосов
/ 24 мая 2019

Вот довольно неэффективное решение, которое не использует генератор (для платформ, которые еще не поддерживают функции генератора)

const combinations = arrayA.reduce((previous, current) => {

    if (current.length === 0)
        return previous;

    const accumulate = current.map(x => {

        if (previous.length === 0)
            return current;

        return previous.map(y => {
            return [x, y];
        });
    });

    // Flatten combinations
    return accumulate.reduce((acc, x) => [...acc, ...x]);
});

combinations.forEach(combination => console.log(combination));
...