Keeping a for loop variable after loop execution - javascript

I am trying to keep a for loop variable after its execution, since the condition will be changing through another for loop. Here's my exemple:
l = 0;
for (var i = 0;i<5:i++){
for(var l; l<l+i;l++){
}
}
My goal here is to remember the value of l when I'm leaving the for loop, and keep it for the next execution with the new condition. I understand this is vague but any help is appreciated.

Just use a while loop:
var l = 0;
for (var i = 0;i<5:i++){
while(l < l+i) {
// do stuff
l++;
}
// Here you have the value of l when breaked out of the loop
}

Your code already works as expected, the var l declares the variable in the outer scope so that you can access it outside of the loop.
You will however need to fix the typo (:->;) and the infinite loop (l<l+i is always true for positive i), and I'd recommend to put the var declaration on the first initialisation of the variable:
var l = 0;
for (var i=0; i<5; i++) {
var end = l+i;
for (; l<end; l++) {
console.log(i, l);
}
}

The other answers will work, however you have no reason to be using var in 2019, and they also don't effectively take advantage of the for loop syntax.
let l = 0;
for (let i = 0; i<5; i++){
for(; l < i + 1; l++){
}
}
console.log(l); // 5
This example maintains the value of l through the outer loop's iterations and then also keeps it at the end.

var l = 0;
for (var i = 0;i<5:i++){
for(l; l<l+i;l++){
}
}
Will let you retain the latest value for l. By the way, without using a break I suspect that this will result in an infinite loop, since l will always be less than l+i (when i is not 0).
Edit: loop not recursion

Related

Can I create a counter that outputs the following counters

I need a 2 counter, i & j that output the following counters for each iteratation:
0,1,2,3,4,1,2,3,4,2,3,4,3,4
Counter variable sequence to achieve the above when output to console.log is as follows:
i,j,j,j,j,i,j,j,j,i,j,j,i,j
With each iteration, when i increments, j must start it's incrementation at i + 1 and must complete it's loop for each incrementation of i.
Each counter value will be used to present option from an array for comparison with one another.
I've tried using a nested for loop and it has not worked. I am also calling a function containing the second loop with some success but want to know if there is a more elegant way to accomplish this.
function createValues() {
for (i = 0; i < 9; i++) {
var counter_i = i;
decreasingLoop(counter_i);
}
}
var k = 1; // counter for inner values loop
function decreasingLoop(get_i) {
for (j = k; j < 10; j++) {
// functions using the counters are entered here.
if (j == 9) { // increments k so that the next time the counter runs it starts at +1 from previous iteration)
k++;
}
}
j = k;
}
I am getting the desired results but want to know if there is a simpler way to achieve the desired outcome.
for(var i = 0; i< 4; i++){
console.log(i)
for(var j = i+1; j<= 4; j++){
console.log(j)
}
}
If you write out your desired output in a different format, the solution may become a little clearer:
i: 0
j: 1,2,3,4
i: 1
j: 2,3,4
i: 2
j: 3,4
i: 3
j: 4
As you can see from the above example, i increases linearly, and only takes the values of 0 through to 3. Each time i takes a new value, j loops from i+1 up to 4. Using this idea, you can create an outer for loop for i (which loops from 0 to 3) and an inner for loop for j which starts at i+1 and finished when j is equal to 4:
for(let i = 0; i <= 3; i++) {
console.log(i);
for(let j = i+1; j <= 4; j++) {
console.log(j);
}
}
Try following nested loop - notice that in second loop initial for value is j=i+1
let n=4, m=5;
for(let i=0; i<n; i++) for(let j=i+1; j<m; j++) {
console.log({i,j});
}

javascript choices for looping over select options

Recently I stole some javascript to select an option in a select element:
var el=document.getElementById('mySelect');
var opts=el.options;
for (var opt, j = 0; opt = opts[j]; j++) {
if (opt.value == 'Apple') {
el.selectedIndex = j;
break;
}
}
It works fine, but as I looked at it I realized it was different from what I would have written:
var el=document.getElementById('mySelect');
for (var j = 0; j < el.options.length; j++) {
if (el.options[j].value == 'Apple') {
el.selectedIndex = j;
break;
}
}
In looking at the first code, what stops the loop if 'Apple' is not found? Which one is 'better'?
In either case, the second expression determines if the loop should continue or stop. In yours,
for (var j = 0; j < el.options.length; j++) {}
it's straightforward, j will increment and as long as j is less than the options length it's true, and at some point it is equal to the length and then it stops. In the other one,
for (var opt, j = 0; opt = opts[j]; j++) {}
the difference is that they are declaring a variable opt and in the second expression set it to the (also incrementing) array index. At some point, j goes beyond the bounds of the array, and opts[j] is undefined. And since an equality expression in JS is the value of the right site, that expression is also undefined, which is falsy, and the loop stops.
As for which is better? Both work. But as you had to scratch your head and wonder about one of them, how much do you want to depend on code that's more difficult to read?
Long story short:
In your for loop var opt is executed once after which you have subsequent opt = data[i].
This is important because:
var opt, data = [1, 2]; // defined once
console.log(opt = data[0]) // 1
console.log(opt = data[1]) // 2
console.log(opt = data[2]) // undefined
When the for loop condition evaluates to falsy it will halt.
So in your case it does stop when opt = data[i] ends up being a falsy value - undefined
Which is at the point of i being 5 and data[i] becoming undefined and being assigned to opt ... which returns as a final result undefined.
You should also consider using this (if ES6 is an option):
var el=document.getElementById('mySelect');
el.selectedIndex = el.options.findIndex(x => x.value === 'Apple')
It is shorted and easier to read :).

Looping an empty array in a not-empty array produces an infinite loop: why?

Why, if a I nest a for-loop executed on an empty array in another for-loop executed on a not empty array, I get a browser-blocking infinite loop as result?
var links = [];
var anchors = ['a', 'b', 'c'];
// not empty loop
for(var i=0; i<anchors.length;i++) {
console.log(anchors[i]);
// empty loop
for(var i=0; i<links.length;i++) {
console.log(links[i]);
}
}
The code inside for(var i=0; i<links.length;i++) is not even evaluated, so why this behavior?
When the second loop executes, you are resetting the i variable (it's equal to 1 after the first cycle in the first for loop) to 0. The same situation in the first loop, when the second one has done first cycle (and the i has 1 value), it's being reseted to 0 once again by the first loop. And so on... till the world's end.
Hovewer - like Ori pointed - if you would use let to declare i variable inside the loops, everything would work smoothly.
var links = [];
var anchors = ['a', 'b', 'c'];
// not empty loop
for (let i = 0; i < anchors.length; i++) {
console.log(anchors[i]);
// empty loop
for (let i = 0; i < links.length; i++) {
console.log(links[i]);
}
}
Ok, so if the nested array is empy, its length is 0, so:
for(var i=0; i<0;i++) {
console.log(links[i]);
}
"i" will never be 0 and the loop will be infinite...
Because link array has length = 0. When you will execute this code
for(var i=0; i<links.length;i++)
1) variable assigned value 0
2) get links.length - it is 0.
3) because 0 < 1,
console.log(links[i]);
will not evaluated

es6 What makes Block-Scoped Variables different?

Looking at http://es6-features.org/#BlockScopedVariables
What a difference between
for (let i = 0; i < a.length; i++) { let x = a[i] … }
and
for (var i = 0; i < a.length; i++) { var x = a[i] … }
I understand in example they move declaration of variables out of block
var i, x, y
for (i = 0; i < a.length; i++)
{
x = a[i] …
}
but is there any reason for it ? why not to include declaration inside the block ? Is it a bad practice or performance hit ?
Just want to understand.
Thanks.
Block scoped variables are simply not available outside their containing block. This is easy to illustrate with an example
for (let i = 0; i < 2; i++) console.info('inner loop i', i);
try {
console.info('after loop i', i);
} catch (e) {
console.error(e.message)
}
for (var j = 0; j < 2; j++) console.info('inner loop j', j);
console.info('after loop j', j);
The primary difference is scope.
Before ES6, you were stuck using var. When using var, variables were defined in the scope of the enclosing function. If there is no function, then they are defined on the global object (typically window). This made it difficult to have two variables named the same, but in different scopes without running into conflicts.
let helps to solve this problem by allowing you to scope variables to the enclosing block, like an if or for loop.
For example, one common issue was nested for loops:
for(var i = 0; i < 4; i++){ // loop 1
console.log(i); // 0
for(var i = 0; i < 4; i++){ // loop 2
}
console.log(i); // 4 - since i was changed by loop 2, loop 1 is now unstable and will skip
}
In the example above, the problem is eliminated using let instead - each i variable is scoped to it's own block.
As for any differences in performance, I can't say. If someone else knows, I'd love to know.

JavaScript: replace param with a local variable?

If I have a funtion like this:
function xyz(b)
{
for(var i = 0; i < b.length; i++)
{
// do something with b items...
}
}
... wouldn't it be more memory-friendly if I were to assign b to a local variable inside of that function before working with its items?
function xyz(b)
{
var c = b;
for(var i = 0; i < c.length; i++)
{
// do something with c items...
}
}
In your example both b and c are local variables since they only exist in the function. So your code will actually be a bit less performant.
Side note - if you want your code to be more performant you should calculate c.length only once for the whole for loop. In your example you're calculating it for every iteration of the loop. Instead you can do as follows:
for (var i = 0, cLen = c.length; i < cLen; i++)
This way it calculates it only once before starting the loop.

Categories

Resources