如何缩放循环以减少变量

时间:2018-04-05 09:31:08

标签: javascript loops decrement

首先,为糟糕的标题道歉。这是我能想到的最好的。

我在Javascript中提出了一个简单的循环,它使用两个变量,每隔一次迭代减1。这是代码:

for(let i = j = 999; j > 0; j > i ? j-- : i--) {do_something_here}

你得到的输出是:

i:  999  j:  999
i:  998  j:  999
i:  998  j:  998
i:  997  j:  998
i:  997  j:  997
i:  996  j:  997
i:  996  j:  996
i:  995  j:  996
i:  995  j:  995

我的问题:我怎样才能缩放这个以减少任意数量的变量?有没有办法修改循环,以便如果我有4个索引(例如i,j,k,m),代码会动态识别索引的数量?

6 个答案:

答案 0 :(得分:1)

您可以使用数组存储任意数量的变量,您可以尝试这样的事情:



var iterations = 10, index = 0, arr = [999, 999]; // array of variables
console.log("i: ", arr[0], "j: ", arr[1]);
for(var k = 1; k < iterations ; k++){
  arr[index]--;
  index = (index + 1) % arr.length;
  console.log("i: ", arr[0], "j: ", arr[1]);
}
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您可以尝试以下

/* noOfVars -> Number of variables min. 1,
 * max -> init value of each variable */
function scaleLoop(noOfVars, max) {
  let obj = {};
  for (var i = 1; i <= noOfVars; i++) {
     obj["index" + i] = max;
  }
  
  for (var j = 1; j <= max; j++) {
     for (var i = 1; i <= noOfVars; i++) {
        obj["index" + i]--;
        console.log(obj);
     }
  }
}

scaleLoop(3, 4);

答案 2 :(得分:0)

这是一个非常适合ES6功能的问题,与发电机功能相结合。请考虑以下事项:

const parallelDecrement = function*(noVars, startingValue = 999, endingValue = 0) {
    values = Array(noVars).fill(startingValue);
    while(values[noVars-1]){
        yield values;
        let indexToDecrement = values.indexOf(values[0] + 1) % noVars;
        values[indexToDecrement  === -1 ? 0 : indexToDecrement]--;  
    }
}


for( let [i, j, k] of parallelDecrement(3) ) {
    console.log(i, j, k)
}

或者更多变量...

for( let [i, j, k, l, m] of parallelDecrement(5) ){
    console.log(i, j, k, l, m)
}

输出:

999 999 999 999 999
998 999 999 999 999
...
1 2 2 2 2
1 1 2 2 2
1 1 1 2 2
1 1 1 1 2
1 1 1 1 1
1 1 1 1
0 0 1 1 1
0 0 0 1 1
0 0 0 0 1

答案 3 :(得分:0)

假设已定义的迭代次数,每步的偏移量以及您希望按顺序将操作应用于一系列变量。我可能会用一个函数来做这个:

let iterations = 100;
let offset = -1;
let values = [100, 200, 300, 100];

for(let i = 0; i < 0; i++){
    sequentialAdd(offset, values);
}

function sequentialAdd(offset, values){
    //creating a persistent local scope on the function
    //just assigning it to a variable for readability/portability
    let thisFn = sequentialAdd;
    if(typeof thisFn.index === 'undefined'){
          thisFn.index = 0;
    }
    values[thisFn.index] = values[thisFn.index] + operation;
    thisFn.index++;
    if(thisFn.index > values.length){
        thisFn.index = 0;
    }
}

当然,通过在开始时更改变量,您可以通过多种方式对其进行调整。例如。你可以使迭代=值数组中的最高值。

答案 4 :(得分:0)

我无法弄清楚做这种事情的原因,因此我在评论中询问这是否是一个挑战。

几天前尝试过循环/递归,你的问题对我来说似乎是一个很好的挑战。所以,我将提供一个使用递归的解决方案并尝试彻底。

在编写复杂的递归循环之前,让我们先了解一下。首先,让我们尝试使用递归编写以下简单的for循环:

for (var i = 0; i < 10; i++) {
    console.log(i);
}

变为

function customLoop(index, target, step, callback) {
    if (index < target) {
        callback(index);
        index += step;
        customLoop(index, target, step, callback);
    }
}

customLoop(0, 10, 1, function (index) {
    console.log(index);
});

接下来,将您提供的for循环转换为递归:

for (let i = j = 999; j > 0; j > i ? j-- : i--) { console.log(i, j) }

变为

function customLoop(a, b, callback) {
    if (b > 0) {
        callback(a, b);
        if (a < b) {
            b--;
        } else {
            a--;
        }
        customLoop(a, b, callback);
    }
}

customLoop(50, 50, function (a, b) {
    console.log(a, b);
});

最后,编写一个以多个值作为索引的递归。如果您将您的值视为一维数组,那么您所做的基本上是一次两个值。

(我可以绘制一个花哨的图形来形象化,但我现在没有时间。所以,也许以后。)

function customLoop(array, callback, startIndex) {
    var startIndex = startIndex || 0;
    if (startIndex < array.length - 1 && array[array.length - 1] > 0) {
        var index_a = startIndex;
        var index_b = index_a + 1;
        var a = array[index_a];
        var b = array[index_b];
        if (callback) {
            callback.apply(null, array);
        }
        if (a < b) {
            array[index_b]--;
            startIndex = index_b;
            if (startIndex >= array.length - 1) {
                startIndex = 0;
            }
            customLoop(array, callback, startIndex);
        } else {
            array[index_a]--;
            customLoop(array, callback, startIndex);
        }
    }
}

customLoop([20, 20, 20, 20, 20], function (a, b, c, d, e) {
    console.log(a, b, c, d, e);
});

您可能需要调整代码以使其符合您的需求。另外,我不知道我的解决方案的性能。它可能比其他解决方案更慢或更快。所以,测试一下。

答案 5 :(得分:-1)

如果&#39; j&#39;和&#39;我&#39;具有相同的值,为什么要在循环中声明这两个?

你为什么不这样做?

let controls = {
  'homeboxpackage_id': new FormControl('', Validators.required)
};

for(let i = 0;i <  this.homeboxsp.length;i++)
{
  controls['active-'+i] = new FormControl(this.homeboxsp[i].active =='1', Validators.required)
}
    this.myform = new FormGroup(controls);