Создание комбинаций в JavaScript

Допустим, у меня есть несколько наборов параметров в Javascript.

var color  =  ["red", "blue", "green","yellow"];
var size   =  ["small", "medium", "large"];
var weight =  ["heavy", "light"];

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

["red and small and heavy", "red and small and light", "red and medium and heavy" ...]

Однако здесь есть оговорка

Эта функция должна принимать любое количество наборов параметров

У меня есть ощущение, что правильный способ сделать это - это пройти через какое-то дерево, но еще слишком рано, чтобы полностью обдумать это, и я еще не пил кофе.


person Greg Guida    schedule 11.01.2012    source источник


Ответы (4)


function permutations(choices, callback, prefix) {
    if(!choices.length) {
        return callback(prefix);
    }
    for(var c = 0; c < choices[0].length; c++) {
        permutations(choices.slice(1), callback, (prefix || []).concat(choices[0][c]));
    }
}

var color  =  ["red", "blue", "green","yellow"];
var size   =  ["small", "medium", "large"];
var weight =  ["heavy", "light"];

permutations([color, size, weight], console.log.bind(console));

Кажется, работает...

[ 'red', 'small', 'heavy' ]
[ 'red', 'small', 'light' ]
[ 'red', 'medium', 'heavy' ]
[ 'red', 'medium', 'light' ]
[ 'red', 'large', 'heavy' ]
[ 'red', 'large', 'light' ]
[ 'blue', 'small', 'heavy' ]
[ 'blue', 'small', 'light' ]
[ 'blue', 'medium', 'heavy' ]
[ 'blue', 'medium', 'light' ]
[ 'blue', 'large', 'heavy' ]
[ 'blue', 'large', 'light' ]
[ 'green', 'small', 'heavy' ]
[ 'green', 'small', 'light' ]
[ 'green', 'medium', 'heavy' ]
[ 'green', 'medium', 'light' ]
[ 'green', 'large', 'heavy' ]
[ 'green', 'large', 'light' ]
[ 'yellow', 'small', 'heavy' ]
[ 'yellow', 'small', 'light' ]
[ 'yellow', 'medium', 'heavy' ]
[ 'yellow', 'medium', 'light' ]
[ 'yellow', 'large', 'heavy' ]
[ 'yellow', 'large', 'light' ]
person AKX    schedule 11.01.2012
comment
не работает в отладчике Chrome, если вы не оберните console.log в анонимную функцию. в любом случае классная работа! - person Greg Guida; 11.01.2012
comment
Извините, да. Я тестировал это в node.js 0.6.x, а не в браузере. Забыл указать это в посте. - person AKX; 12.01.2012
comment
Функция console.log, упомянутая в пункте 1 выше, должна выглядеть так: function log(message){ if(typeof console == object){ console.log(message); } } Затем измените вызов функции на: комбинации([цвет, размер, вес], журнал); - person Meetai.com; 07.10.2012
comment
'bind' - ваш друг: комбинации([цвет, размер, вес], console.log.bind(console)); - person zaphod1984; 10.06.2015


Обход дерева - это путь, а точнее рекурсия.

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

person Shamim Hafiz    schedule 11.01.2012

Функция console.log, упомянутая в пункте 1 выше, должна выглядеть так:

function log(message){
    if(typeof console == "object"){
        console.log(message);
    }
}

Затем измените вызов функции на:

combinations([color, size, weight], log);
person Meetai.com    schedule 07.10.2012