I'm trying build a loop with an array of 12 positions, wrapping 5 items with and insert another code after this interval, but for some reason the loop only goes up to 10.
Why the loop stops at tenth position only when the array has 11 or 12 positions?
Someone can explain me the reason about it?
let x = [0,1,2,3,4,5,6,7,8,9,10,11];
x.map(_=> {
console.log("<div>");
x.splice(0,5).map((y,k)=>
console.log('item: ' + y)
)
console.log("</div>");
console.log('interval of 5 text');
});
x = [0,1,2,3,4,5,6,7,8,9,10,11];
for(i=0; i < x.length; i++){
let x2 = x.splice(0,5);
console.log("<div>");
for(j=0; j < x2.length; j++){
console.log('item: ' + x2[j]);
}
console.log("</div>");
console.log('interval of 5');
}
To answer your question why.
Let me clear that loop a bit and just keep the splice method (since it is the thing that mutates your array) and log the length of the array x to console in each iteration.
x = [0,1,2,3,4,5,6,7,8,9,10,11];
for(var i=0; i < x.length; i++){
let x2 = x.splice(0,5);
console.log(x.length);
}
And let's see what happens.
loop execution:
------------------------------
i | x.length | i < x.length
------------------------------
0 | 12 | true
1 | 7 | true
2 | 2 | false
that is why your loop ends after the second iteration (which is the 10th position since you are processing 5 positions in a single iteration).
One way to have a code which performs that mentioned logic and leaves the array clear afterwards would be this.
Create a function that does the following:
take the array and size of the group
create copy of that array
get the right number of iterations
perform your logic
return (empty array) and reassign the old array
To get the correct number of iterations, divide length of the array by the size of group and round it up.
let x = [0,1,2,3,4,5,6,7,8,9,10,11];
function customArrayLoop(arr, toTake) {
const arrCopy = [...arr];
const loopMax = Math.ceil(x.length / toTake);
for (let i = 0; i < loopMax; i++) {
let x2 = arrCopy.splice(0,5);
console.log("<div>");
for(let j=0; j < x2.length; j++){
console.log('item: ' + x2[j]);
}
console.log("</div>");
console.log('interval of 5');
}
return arrCopy;
}
x = customArrayLoop(x, 5);
console.log(x);
While still not the best you can get (since you want to keep that internal logic of the loop), it is much safer solution.
It is because you are altering your original array while iterating:
let x2 = x.splice(0,5); // should be avoided.
With each alteration the length of your array also decreases.
Use Array.slice(...) instead Array.splice(...)
let x = [0,1,2,3,4,5,6,7,8,9,10,11]
After a = **x.splice(0,5)** =>
x => [5,6,7,8,9,10,11]
a => [0,1,2,3,4]
After a = **x.slice(0,5)** =>
x => [0,1,2,3,4,5,6,7,8,9,10,11]
a => [0,1,2,3,4]
Since you use ( ... i < x.length ... ) condition, after two splice operation you reach the end of the array. (with loop you get the same case)
I'm trying to write a program to find the smallest common multiple of the provided parameters that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters.
The range will be an array of two numbers that will not necessarily be in numerical order.
For example, for 1 and 3 - find the smallest common multiple of both 1 and 3 that is evenly divisible by all numbers between 1 and 3.
Why does the loop stop at i = 510,000 (or something close to that) instead of 7,000,000, as I set it?
I also have a screenshot with the output:
function smallestCommons(arr) {
var start;
var finish;
var something;
if(arr[0] < arr[1]){start = arr[0]; finish = arr[1];}else{
start = arr[1]; finish = arr[0];
}
for(var i = finish;i <= 7000000;i++){
var boolea = true;
for(var j = start;j <= finish;j++){
if(i % j !== 0){boolea = false;break;} // 2 % 1
}
if(boolea)return i;
something = i;
}
console.log("final i = " + i);
return 0;
}
Try to add this at the beginning of your loop
// noprotect
it must be that jsbin is forcing your code to exit from the loop. See source
I would love some explanation of this (taken from javascriptkit.com):
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
So testList() is pretty straightforward.
I tried following the first function step by step and this is what I figured it would return:
item 1 1
item 2 2
item 3 3
What I don't get is how result is returned as item 3 undefined 3 times - why undefined, and why only item 3?
-As I'm trying to learn, I'm not looking to get this to work, but rather understand what part I'm missing and why it doesn't come out as I would expect it to.
What's the problem?
The function in the for loop has a reference to i but i is changing in each iteration, so when you call the function declared in the loop it will use i with it's last value(3).
A simple closure will save the index value untouched:
for (var i = 0; i < list.length; i++) {
(function(index){
var item = 'item' + list[index]; // why ?
result.push( function() {alert(item + ' ' + list[index])} );
})(i);
}
Note:
Why do you need var item = 'item' + list[index]; if you re-lookup the value in the list?
Update based on question changed,
Because i has the final value- 3 which makes your code in the final iteration:
// i equals to 2 here
var item = 'item' + list[i]; // gives item3
result.push( function() {alert(item + ' ' + list[i])} );
// now `i` is changed to three so we don't enter the loop.
Values:
item == "item3"
i == 3
list[i] == list[3] == undefined.
It is important to understand that array returned by buildList contains 3 functions that share the same closure. Each time local variable of that closure is changed - it affects all functions that share it. In other words, i, item and list variables of all functions in result are the same. After loop has iterated through list, the value of i remains equal to 3 and it is true for all functions in result because they share reference to that variable. So, the answers to you questions will be like that:
why undefined?
Because list[3] === undefined
why item 3?
Because last time item variable was modified is when i was 2 and for executed its body (list[2] === 3 therefore item === 'item 3')
For some reason the second for loop is starting at 1. I do realize that first for loop i starts at one. That's is meant to be. However, even though j for loop says to start at 0, it starts at 1 anyways.
var findWinners = function (playersRay) {
var players = playersRay;
var results = new Array();
//getdealers dealers hand and info
var dealerHand = players[0]
var dealerScore = dealerHand.getScore()
var dealerBust = dealerScore > 21 ? true : false;
//loops through all players; skips dealer (array position 0)
var numPlayers = players.length;
for (var i=1; i<numPlayers; i++) {
//loops through all the players hands.
//player might have more than 1 hand if he splits his cards
var player = players[i];
var numHands = player.length;
results[i] = new Array();
for (var j=0; j<numHands; j++)
var handScore = player[j].getScore();
if (handScore > 21) {
results[i][j] = false;
}
else if (dealerScore > 21) {
results[i][j] = true;
}
else if (handScore > dealerScore) {
results[i][j] = true;
}
else {
results[i][j] = false;
}
}
return results;
}
It returns this: [undefined, [undefined, true]]
It should return this: [undefined, [true]]
Just in case you want to know. A sample playersRay is: [Object, [Object]]
The object has information about the dealer's or player's blackjack hand.
Link to full code: https://docs.google.com/open?id=0BxvwY0fUFc3aMTdTOXU0b0ttamM
In Javascript, when you omit the curly braces around a statement, it only runs the first line. The behavior appears to omit only the first index, when I suspect there's only two. So if you add some more to iterate, you should notice it's actually just running the last index.
For example:
for (var i = 0; i < 10; i++)
console.log('First line: ', i);
console.log('Second line: ', i);
http://jsfiddle.net/MMQD8/
Gives:
First line: 0
First line: 1
First line: 2
First line: 3
First line: 4
First line: 5
First line: 6
First line: 7
First line: 8
First line: 9
Second line: 10
MDN explains it thusly:
statement
A statement that is executed as long as the condition
evaluates to true. To execute multiple statements within the loop, use a block
statement ({ ... }) to group those statements.
for (var i=0;i<5;++i){
alert(i);
}
for (var i=0;i<5;i++){
alert(i);
}
These two constructs return the same result: 0,1,2,3,4. Why? What are the differences between them? Does it matter what increment i use in for loop?
If you put ++ in front of the variable you increment the value before returning it (in that statement), if you put it behind you return the value, then increment it afterwards. Since you are doing nothing with the value in the statement the result after said statement is the same.
Consider this:
var i = 0;
var a = ++i; // a is 1
var b = i++; // b is also 1, i is now 2.
The former is a pre-increment, the latter a post-increment.
The difference is nothing your example as you're not assigning the result to anything, but show themselves quite alot when assigning the result to another variable.
var i = 0;
alert(i); // alerts "0"
var j = i++;
alert(j); // alerts "0" but i = 1
var k = ++i;
alert(k); // alerts "2" and i = 2
Live example: http://jsfiddle.net/ggUGX/
for a loop you dont see any difference, but the ++i increments and then returns the value wheras i++ returns a value and then increments. If you have code like
var a = myarray[++i]
and
var a = mayarray[i++];
they will return differnet values
These two code blocks should have the same output. The difference between i++ and ++i is the order in which the variable i is incremented and is only important when using the value of i at the same time.
For instance, ++i and i++ do effectively the same thing unless you're using it like so:
y = i++;
or
y = ++i;
In the first example i is incremented AFTER y is set to its value (so if i = 0, y = 0, then i = 1). In the second example i is incremented BEFORE y is set to its value (so if i = 0, i = 1, y = 1).
Because you do not use i++ in a similar fashion in a for statement, it has no effective difference.
i++ or ++i in the for loop executes as a different statements. So, putting i++ or ++i in for loop doesn't make any difference.