Все варианты матрицы - PullRequest
0 голосов
/ 31 марта 2020

Я пытаюсь написать алгоритм для получения всех возможных вариаций матрицы в JavaScript. Вот чего я хочу достичь:

blue,red
male,female,other
small,medium,large

-----------------

blue,male,small
blue,male,medium
blue,male,large

blue,female,small,
blue,female,medium,
blue,female,large

blue,other,small,
blue,other,medium,
blue,other,large

red,male,small
red,male,medium
red,male,large

red,female,small,
red,female,medium,
red,female,large

red,other,small,
red,other,medium,
red,other,large

Есть идеи, как это можно сделать?

Ответы [ 2 ]

1 голос
/ 31 марта 2020

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

Вы можете обобщить это для произвольного списка, просматривая списки в стиле одометра. (Однако каждый ди git одометра может иметь свой диапазон.)

Вот как:

function cartesian(m) {
    const res = [];
    const index = [];    // current index
    const max = [];      // length of sublists

    for (let i = 0; i < m.length; i++) {
        index.push(0);
        max.push(m[i].length);
    }

    for (;;) {
        res.push(index.map((i, j) => m[j][i]));

        let i = 0;
        index[i]++;

        while (index[i] == max[i]) {
            index[i] = 0;
            i++;

            if (i == m.length) return res;
            index[i]++;
        }
    }
}

Назовите это так:

const m = [
    ["blue", "red"],
    ["male", "female", "other"],
    ["small", "medium", "large"],
];

const p = cartesian(m);

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

1 голос
/ 31 марта 2020

Вы можете перебирать массивы, используя Reduce:

let data = ['blue','red']
let data2 =['male','female','other']
let data3 =['small','medium','large']

let result = data.reduce((acc,rec) => {
 
  return acc.concat(data2.reduce((acc2, rec2) => {
    
    return acc2.concat(data3.reduce((acc3,rec3) =>{
      
      return acc3.concat([`${rec}, ${rec2}, ${rec3}`])
    },[]))
  },[]))
},[])

console.log(result)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...