NodeJS 如何将下面的一系列for循环缩小为一个更不紧凑的代码?

0md85ypi  于 2023-02-03  发布在  Node.js
关注(0)|答案(8)|浏览(106)

我有下面的代码,它遵循循环的模式,我有一种感觉,代码可以缩小到递归一样的代码或任何不那么难看的代码,但我无法弄清楚。
我想在javascript中运行六个循环,从100010000,如果可能的话,我希望缩小代码。
我是一个初学者在编码,但各种方法都是可以接受的我。
我更新的代码,因为以前的代码可能会得到一些用户模棱两可。

function dummyFunc(x,y){
    if( some logic for x == some logic for y){
         return true;
    }
    return false;
}

for(var i = 1000;i < 10000;i++){
  for(var j = 1000;j < 10000;j++){
    if(dummyFunc(i,j)){
      for(var k = 1000;k < 10000;k++){
        if(dummyFunc(j,k)){
          for(var l = 1000;l < 10000;l++){
            if(dummyFunc(k,l)){
              for(var m = 1000;m < 10000;m++){
                if(dummyFunc(l,m)){
                  for(var n = 1000;n < 10000;n++){
                     if(dummyFunc(m,n)){
                        break;
                     }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
kd3sttzy

kd3sttzy1#

你可以把for循环提取到一个函数中:

function range(start, end, callback) {
   for(let i = start, start < end, i++)
     callback(i);
 }

可用作:

range(1000, 10000, i => {
   range(1000, 10000, j => {
     range(1000, 10000, k => {
       range(1000, 10000, l => {
        range(1000, 10000, m => {
          range(1000, 10000, n => {
            console.log(i, j, k, l, m, n);
         });
       });
     });
   });
 });

为了进一步简化,您可以使用生成器来生成一个值数组,您可以对该数组进行反结构化:

function* ranges(start, end, repeats) {
    if(repeats > 1) {
      for(const values of ranges(start, end, repeats - 1)) {
         for(const value of ranges(start, end, 0)) {
             yield values.concat(value);
         }
      }
    } else {
      for(let i = start; i < end; i++) 
        yield [i];
   }
}

可用作:

for(const [i, j, k, l, m, n] of ranges(1000, 10000, 6)) {
     console.log(i, j, k, l, m, n);
  }
ct3nt3jp

ct3nt3jp2#

使用下面的代码。不要返回true或false,而是在dummyFunc内部启动循环,这将递归调用函数。

function dummyFunc(x,y){
    if( some logic for x == some logic for y)
        for(var i = 1000;i < 10000;i++)
            for(var j = 1000;j < 10000;j++)
                dummyFunc(i,j);
}

for(var i = 1000;i < 10000;i++)
   for(var j = 1000;j < 10000;j++)
      dummyFunc(i,j);

为了更清楚地说明递归函数是如何工作的(以通常的递归函数风格编写--如果满足某个条件,则返回,否则再次调用函数),您可以将其编写如下

function dummyFunc(x,y){
    if( !(some logic for x == some logic for y))
         return;

    for(var i = 1000;i < 10000;i++)
        for(var j = 1000;j < 10000;j++)
            dummyFunc(i,j);
}

for(var i = 1000;i < 10000;i++)
   for(var j = 1000;j < 10000;j++)
      dummyFunc(i,j);
e1xvtsh3

e1xvtsh33#

下面是完整的简化代码

function getDeeper(i, j, start, end, level) {
    if(j === end && (i = (i+1)) && (j = start)) {}
    if(dummyFunc(i, j)) {
        if(level === 4) return;
        getDeeper(j, start, start, end, ++level); 
    }
    getDeeper(i, ++j, start, end, level);
}

getDeeper(1000, 1000, 1000, 10000, 0);
kgqe7b3p

kgqe7b3p4#

由于您的问题是How do I minify the following series of for loops into a less compact code?,并且不是专门要求更好的代码示例,因此我将向您展示如何钓鱼,而不是给您鱼。
您需要阅读有关Structured program theorem的信息:
它指出一类控制流图(在这里历史上称为图)可以计算任何可计算函数,只要它以三种特定的方式(控制结构)组合子程序。
1.执行一个子程序,然后执行另一个子程序(序列)
1.根据布尔表达式的值执行两个子程序中的一个(选择)
1.只要布尔表达式为真,就重复执行子程序(迭代)
同样值得一阅读的是科拉多·玻姆和朱塞佩·雅科皮尼的Flow Diagrams, Turing Machines And Languages With Only Two Formation Rules,该定理是以他们的名字命名的。
所以如果我正确理解了你的代码,那么虽然这个例子看起来像是一个很长的计算任务
如果我们假设你的浏览器每秒进行1000 * 1000次迭代,这将需要1000 * 1000 * 1000 * 1000秒才能完成。这是非常长的(317个世纪)
如X1 E2 F1 X所示,
根据我对 predicate 的丰富经验,predicate只返回truefalse,如果你知道一旦它是true,你就可以停止处理,因为你有结果,另一方面,如果结果是false,你就需要处理所有的结果。真实的的技巧不是对所有的值进行暴力处理,而是快速排除对解决方案没有帮助的输入组合。
虽然我不知道你到底想做什么,但我也想看看Binary decision diagram和/或Constraint satisfaction,它们是简化复杂问题的好方法。

23c0lvtd

23c0lvtd5#

根据您提供的代码,您可以简化为:

function dummyFunc(x,y){
    if( some logic for x == some logic for y){
         return true;
    }
    return false;
}

for(var i = 1000;i < 10000;i++) {
  for(var j = 1000;j < 10000;j++) {
    if(dummyFunc(i,j)) {
      break;
    }
  }
}

你可能会说我把你的例子看得太字面了,但希望它能回答你的问题,或者说明为什么你需要一个更好的例子来得到更好的答案。

vwkv1x7d

vwkv1x7d6#

每次都重复相同的 for 循环,这样就可以在函数内部移动它

function dummyFunc(x) {
    for (y = 1000; y < 10000; y++) {
        if (some logic for x == some logic for y) {
            return y;
        }
    }
    return false;
}

for (var i = 1000; i < 10000; i++) {
    if (j = dummyFunc(i)) {
        if (k = dummyFunc(j)) {
            if (l = dummyFunc(k)) {
                if (m = dummyFunc(l)) {
                    if (n = dummyFunc(m)) {
                        break;
                    }
                }
            }
        }
    }
}

如果你需要i,j,k,l,m和n变量如果你不需要这些变量通过使用递归函数这个解给出了问题中的等于n变量

function dummyFunc(x) {
    numberOfLoops = 6;
    for (y = 1000; y < 10000; y++) {
        if (some logic forr x == some logic forr y) {
            if (numberOfLoops == 0) {
                return n;
            }
            n=dummyFunc(x)
            numberOfLoops--;
        }
    }
    return false;
}
for (var i = 1000; i < 10000; i++) {
    n = dummyFunc(i)
}

我还没有检查我的代码,你的意见会很有帮助

s8vozzvw

s8vozzvw7#

我仍然不知道你为什么要这么做,但是下面是两个可能的解决方案,这取决于你在“休息”时想要的行为。这两个都不是很漂亮,但是它们都能解决所描述的问题。
解决方案(A)-仅中断最内部的循环,这将与问题中描述的行为完全匹配。

function loopenstein(minn, maxx, maxDepth, dummyCall) {

  function recursiveLoop(i, minn, maxx, depth, dummyCall) {
    for (var j = minn; j < maxx; j++)
      if (dummyFunc(i, j)) {
        if (depth <= 0) {
          console.log("break me daddy...")
          return;
        }
        recursiveLoop(j, minn, maxx, depth - 1, dummyCall)) 
      }
  }
  for (var i = minn; i < maxx; i++) {
        recursiveLoop(i, minn, maxx, maxDepth, dummyCall))
  }
}
/* usage */
loopenstein(1000, 10000, 6, dummyFunc)

解决方案(B)-一旦dummyFunc在第6个循环中返回true,则完全中断所有循环。

function loopenstein(minn, maxx, maxDepth, dummyCall) {
  //recursive helper function
  function loopensteinHelper(i, minn, maxx, depth, dummyCall) {
    for (var j = minn; j < maxx; j++)
      if (dummyFunc(i, j)) {
        if (depth <= 0) {
          console.log("break me daddy...")
          return true;

        } else if (loopensteinHelper(j, minn, maxx, depth - 1, dummyCall)) {
          return true;
      }
    return false;
  }

  for (var i = minn; i < maxx; i++) {
    if (loopensteinHelper(i, minn, maxx, maxDepth, dummyCall)) {
      return true;
    }
  }
  return false;
}
/* usage */
var isFound = loopenstein(1000, 10000, 6, dummyFunc)
lnvxswe2

lnvxswe28#

我建议使用promise。下面是代码的修改版本:

var looper = function(start = 1000, end = 10000) {
    return new Promise(function(resolve, reject) {
        console.log('Starting');
        for (; start <= end; start++) {
            // Your computation goes here
        }
        resolve();
    });
}

现在,如果你想运行一个循环3次,可以这样使用:
活套().然后(活套()).然后(活套())
如果需要运行循环4次,请使用:
looper().然后(looper()).然后(looper()).然后(looper())
您可以了解有关Promises here的详细信息

相关问题