Используя генераторы, это может быть достигнуто довольно элегантно:
function* loop(depth, start, times, prev = []) {
if(depth <= 0) {
yield prev;
return;
}
for(let current = start; current < times; current++) {
yield* loop(depth - 1, current + 1, times, [...prev, current]);
}
}
Используется как:
for(const [j, k, l, m] of loop(4, /*times from*/ 0, /* till*/ 5)) {
//...
}
Выше будет повторяться так же, как ваши циклы for, наверняка вы можете сделатьнамного больше с генераторами, например, непосредственно генерирующими комбинации:
const identity = _ => _;
function* take(n, of, mapper = identity, prev = []) {
if(!of.length) return;
if(prev.length >= n) {
yield mapper(prev);
return;
}
for(let i = 0; i < of.length; i++) {
yield* take(n, of slice(i + 1), mapper, [...prev, of[i]]);
}
}
for(const combo of take(4, /*of*/ deck, it => it.reduce((a, b) => a + b))) {
//...
}
Или если вам нужен массив
function toArray(iterator) {
let result = [], value;
while(!({ value } = iterator.next()).done) result.push(value);
return result;
}
const combos = toArray(take(4, /*of*/ deck, it => it.reduce((a, b) => a + b)));