A flexible solution is to start with a card with all the features set to zero, then use a for loop which gets the next card in the sequence, within an outer while loop that terminates when no more valid cards can be generated. (jsfiddle).
function createCards(dim) {
var card = [], cards = [];
while (card.length < dim.length) card.push(0);
while (card.length === dim.length) {
cards.push(card.slice(0));
for (var feature = 0; ++card[feature] === dim[feature]; feature++) {
card[feature] = 0;
}
}
return cards;
}
console.log(createCards([3, 3, 3, 3]));
Or similarly (but counting down instead of up)
function createCards(dim) {
var cards = [], card = dim.slice(0);
while (true) {
cards.push(card.slice(0));
for (var feature = dim.length - 1; !--card[feature]; card[feature] = dim[feature--]) {
if (feature < 1) return cards;
}
}
}
Alternatively, loop through the current set of cards, progressively adding variations of each feature.
function createCards(dim) {
var cards = [dim.slice(0)];
for (var feature = 0; feature < dim.length; feature++) {
var numberOfCards = cards.length;
for (var variation = dim[feature] - 1; variation > 0; variation--) {
for (var i = 0; i < numberOfCards; i++) {
var card = cards[i].slice(0);
card[feature] = variation;
cards.push(card);
}
}
}
return cards;
}
These should have the same result as mellamokb's answer.