【问题标题】:Is there a way to make a "for loop of for loops"?有没有办法制作“for循环的for循环”?
【发布时间】:2019-06-05 20:11:31
【问题描述】:

我正在尝试为自己编写一个扑克计算器,并且我有一个深度为 5 级的 for 循环。

为此,我一个接一个地嵌套了 for 循环。我正在寻找一种方法来简单地使用 1 个循环(或函数),它可以告诉我想要深入多少层。对于此示例,答案是 5,但对于其他示例,它可能是一个更高(更高)的数字,这会很麻烦。我认为递归是一种方法,我只是不知道如何设置它(不太了解递归)。感谢您的帮助,非常感谢。

for(var i=0; i < deck.length; i++){
  for(var j=i+1; j<deck.length; j++){
    for(var k=j+1; k<deck.length;k++){
      for(var m=k+1; m<deck.length;m++){
        for(var n=m+1; n<deck.length;n++){
        combo = deck[i];
        combo += deck[j];
        combo += deck[k];
        combo += deck[m];
        combo += deck[n];
        bighands.push(combo);
        }
      }
    }
  }
}

它有效,我只是想要一种更好/更通用的方法。

【问题讨论】:

  • 您正在寻找递归,例如 DFS。
  • Currying 将是另一种有趣的方式来实现这一点,并使用更实用的方法。
  • 检查 stackoverflow.com/questions/4683539/… 我没有结束这个问题,因为它不是 100% 重复的

标签: javascript arrays data-structures recursive-datastructures array-algorithms


【解决方案1】:

使用生成器可以非常优雅地实现这一点:

  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)));

【讨论】:

    【解决方案2】:

    您可以采用递归方法。

    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; }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多