Есть ли способ сделать "для петли для петель"? - PullRequest
1 голос
/ 05 июня 2019

Я пытаюсь запрограммировать для себя покерный калькулятор, и у меня есть цикл for, который углубляется на 5 уровней.

Для этого я вложил циклы один за другим.Я ищу способ просто использовать 1 цикл (или функцию), который может просто сказать, сколько уровней я хочу пройти.Для этого примера ответ - 5, но для других примеров это может быть большее (намного большее) число, где это было бы громоздко.Я думаю, что рекурсия - это способ сделать это, я просто не знаю, как ее настроить (на самом деле не понимаю, рекурсия).Спасибо за вашу помощь!

Ответы [ 2 ]

2 голосов
/ 05 июня 2019

Используя генераторы, это может быть достигнуто довольно элегантно:

  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)));
1 голос
/ 05 июня 2019

Вы можете использовать рекурсивный подход.

function getHands(array, size, right = []) {
    return array.reduce((r, v, i, a) => {
        var temp = [...right, v];
        if (temp.length === size) {
            r.push(temp.join(' '));
        } else {
            r.push(...getHands(a.slice(i + 1), size, temp));
        }
        return r;
    }, []);
}

var deck = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
    bighands = getHands(deck, 5);

console.log(bighands.length);
console.log(bighands);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...