Nested for loops in javascript - javascript

I was just wondering if I could get some guidance on an issue I am having with nested for loops in javascript.
I currently have the following nested for loop in place
for (var i = 0; i <= score; i++)
{
for (var j = 0; j <= i; j++)
{
var stsc = '<img src="./images/star.png"/>';
}
}
The aim is to get the variable stsc to show the number of stars depending on the count of the score variable.
Currently, it will only show 1 star no matter what the value of score is. I have tried adding stsc outside of the nested loop to no avail. No matter what I do it will show nothing other than 1 star.
Could you point me in the right direction as to how to get it to show the correct number of stars (3 stars if score is 3, 0 stars if score is 0 etc...)
Thanks everyone

var stsc="";
var score=0;
for (var i = 1; i <= score; i++)
{
stsc = stsc +'<img src="./images/star.png"/>';
}
http://jsfiddle.net/m5Btd/1295/

You just need a normal for loop and string concatenation:
var stsc = '';
for (var i = 0; i < score; i++) {
stsc += '<img src="./images/star.png"/>';
}
Think about it like this: You want to create n stars, where n is the value of the score. Hence you have to repeat the process of creating the HTML string n times. That's what a for loop is doing, repeating something until a condition is fulfilled. And instead of overwriting the variable in each iteration, you have to add to it.

You don't need any for loops:
var stsc = score === 0 ? "" : new Array(score + 1).join("<img src=./images/star.png>");

Related

Understanding a JavaScript For Loop

If I have variables and a for loop with a condition set-up like this:
var scores = [23, 53, 85];
var arrayLength = scores.length;
var i;
for(i = 0; i < arrayLength; i++)
Does the i refer to the scores array indexed position of 0, or is i just the counter number, which is set to 0?
I'm kinda confused on understanding what's happening.
Any help is appreciated!
Here you can see it in action:
var scores = [23, 53, 85];
var arrayLength = scores.length;
var i;
for(i = 0; i < arrayLength; i++) {
console.log('i = ' + i + ', scores[i] = ' + scores[i]);
}
console.log('End of for loop: i = ' + i);
One important thing to understand is that i will be incremented until the condition i < arrayLength is not met anymore. So it will reach the value 3 but the for loop will end immediately. Therefore, the code inside the loop is not executed for i = 3.
i is just a counter number which is initially set to 0 and increments up to arrayLength (3 in this case)
i just refers to a number that (in this case) counts up from 0 until arrayLength. You have to explicitly access the values in the array at each i by using scores[i], after which you can modify/use the value in any way you see fit.
i is the counter number.
A for loop works like so:
For each value of array length, use i as a counter variable
each time through the loop increment the variable of i when you are done (i++)
you could expand it like so...
for(i = 0; i < arrayLength; i++)
{
console.log('position ' + i + ' is ' + scores[i]);
}//now that I am done, increment i and go through again until i is no longer less than array length
Right so you have the set the i as a variable by initially going
var i;
Within the for statement you have set the i variable to 0.
for(i = 0; i < arrayLength; i++){
}
Then the for statement is saying if i is less than the array length run the for statement. Each time the for statement runs you are adding 1 to i because of i++;
Every time the for statement will check to see if i is less than the arrayLength if it isnt it will exit out of the for.
So for this instance the for each would run 3 times because the array length is 3.
Make sure you have open and closing brackets on the for statement
So your for statement should look like this.
for(i = 0; i < arrayLength; i++){
}

Function slows down when working with high numbers

I've wrote a script that instead of giving the real average of a set of data returns a windows that contains most data points. Let me show some code:
time.tic()
var selectedAverage = 0;
var highestPointCount = 0;
for (var i = 1; (i*step) <= maxValue; i++) {
var dataPointCount = 0;
for (var j = 0; j < myArray.length; j++) {
if (myArray[j] >= minValue+(i-1)*step && myArray[j] <= minValue+i*step) {
dataPointCount++;
}
}
if (dataPointCount > highestPointCount) {
highestPointCount = dataPointCount;
selectedAverage = (minValue+(i-1)*step)+Math.round(0.5*step);
}
}
console.log(time.toct().ms)
return selectedAverage;
First the step value is calculated by subtracting the minimum value from the maximum value and then deciding by 10. So there are 10 'horizontal' windows. Then the script counts the amount of datapoint within each window and returns a appropriate average.
It appears however that script slows down extremely (sometimes more than 200 times) when an array of larger numbers is passed in (1.000.000 for example). Array lengths are roughly 200 but always the same length so it must be associated with the actual values. Any idea where it is going wrong?
EDIT:
The code to get the step value:
var minValue = myArray.min();
var maxValue = myArray.max();
var step = Math.round((maxValue-minValue)/10);
if (step === 0) {
step = 1
}
The .min() and .max() are prototypes attached to Array. But this all goes very fast. I've measured every step and it is the for loop that slows down.
If I understood your algorithm correctly, this should remove all unnecesary calculations and be much faster:
var arr = [];
var maxQty=0;
var wantedAverage = 0;
for (var j = 0; j < 11; j++) {
arr[j]=0;
}
for (var j = 0; j < myArray.length; j++) {
var stepIndex = Math.floor((myArray[j]-minValue)/step)
arr[stepIndex]+=1;
if(arr[stepIndex] > maxQty ){
wantedAverage = minValue + stepIndex*step +Math.round(0.5*step);
maxQty = arr[stepIndex]
}
}
console.log(maxQty, wantedAverage)
We just iterate over each element of the array only once, and calculate the index of the window it belongs to, adding one to the quantity array. Then we update the wantedAverage if we have a bigger amount of points in window found
There are 2 different things I think of your issue:
Removed unnecessary / repeated calculation
Inside your nested code you have minValue+(i-1)*step and minValue+i*step calculated everytime for the same value of minValue, i and step.
You should pull it up before the 2nd for-loop where it becomes:
var dataPointCount = 0;
var lowerLimit = minValue+(i-1)*step;
var higherLimit = minValue+1*step;
for (var j = 0; j < myArray.length; j++) {
if (myArray[j] >= lowerLimit && myArray[j] <= higherLimit) {
dataPointCount++;
}
}
You got severe performance hit when you are handling big data array are likely caused by memory swapping. From your point of view you are dealing with a single array instance, however when you have such a big array it is unlikely the JavaScript VM has access to consecutive memory space to hold all those values. It is very likely JavaScript VM has to juggle multiple memory blocks that it gets from the operating system and have to spend extra effort to translate which value is where during reading/writing.

Javascript Euler Fibonacci for loop

I'm doing the Euler project problem 2 in which the objective is to sum the even numbers of the fibonacci sequence that have a value of less than 4 million. I've searched a bit and I've seen several solutions using a while loop but nothing simple using a for loop. I'm curious why I'm returning zero with the following code:
var array = [];
array[0] = 0;
array[1] = 1;
var total = 0;
for(var i=2;total<=4000000;i++) {
array[i] = array[i-1] + array[i-2];};
for(var x=0;x<array.length;x++){
if(array[x]%2 === 0){
total += array[x]};};
alert(total);
I'm guessing the problem is in my for loop using the total variable. I couldn't get it to work using array[i]<=4000000 either and I'm really curious behind the why here. Anyone know why this is? What can I change in the for loop condition (second statement) to get a correct total here?
First of all there is an infinite loop at first for. Your condition must be array[i-1] < 4000000. After that your second for loop will find the correct result.
Also for the problem, you don't need to store all fibonacci numbers then find sum of even numbers.
You can calculate sum when calculating fibonacci.
var first = 0;
var second = 1;
var sum = 0;
for(var current=first+second; current < 4000000; current = first+second){
if(current%2 === 0){
sum+=current;
}
first = second;
second = current;
}
I fixed it for you.
var i, data = [ 0, 1 ], total = 0;
for (i = 2; i <= 4000000; i++)
{
data[i] = data[i - 1] + data[i - 2];
if (data[i] % 2 === 0)
{
total += data[i];
}
}
alert(total);
I'm not sure what you termination condition should be like, you say have a value of less than 4 million, but this is ambiguous. Maybe it should be total <= 4000000 or data[i] <= 4000000. Your phrasing is not precise enough.
Sorry but for me your code going in a dead loop. first "for" use total as check but it's never incremented. If you want This is a solution for fibonacci sequence based on dinamic programming with memoization tecnic.
var f1 = 1;
var f2 = 1;
for(var i = 2; i < 40000; i++){
console.info(i, f1, f2);
var temp = f1 + f2;
f1 = f2;
f2 = temp;
}
alert(f2);

why is my loop only seeing the value of the first array element?

function Deal()
{
var suffledDeck:Array;
var playerOneCards: Array;
var playerTwoCards: Array;
var first:int =0;
var second:int = 1;
suffledDeck = new Array();
playerOneCards = new Array();
playerTwoCards = new Array();
//var CardLeft:int = Deck.length;
for(var i = 0; i < Deck.length; i++)
{
Debug.Log(Deck.length);
var ranNum = Random.Range(1,Deck.length);
suffledDeck.Add(Deck[ranNum]);
Debug.Log("suffled deck: " + suffledDeck.length);
}
//var halfDeck: int = (suffledDeck.length / 2);
for(var j = 0; j <=26 ; j++)
{
Debug.Log(first);
Debug.Log(second);
playerOneCards.Add(suffledDeck[first]);
playerTwoCards.Add(suffledDeck[second]);
Debug.Log(playerOneCards[first].img);
Debug.Log(playerTwoCards[second].img);
first += 2;
second += 2;
}
}
when i begin to split the array into 2 separate arrays it begins to ignore every element except the first element. the suffleDeck[] has 52 Card objects loaded in and im trying to split the array so that each player can have there own deck.
Console window for debug purpose: http://puu.sh/2dqZm
I believe the problem is var ranNum = Random.Range(1,Deck.length).
ranNum should be generating a random index between 0 to Deck.length - 1 because array indices start at 0 (not 1).
The problem is with these logging statements:
Debug.Log(playerOneCards[first].img);
Debug.Log(playerTwoCards[second].img);
first and second are valid indexes into suffledDeck, but each player's deck only has half as many cards. Try using j as the subscript in both logging statements instead of first or second.
You should also limit your loop to j < 26, not j <= 26. As it is, you are trying to put 27 cards in each player's deck.
because:
Debug.Log(playerTwoCards[second].img);
here second value us 1 while your array contains only one item that is at zero. causing ArgumentoutofRangeException.
so try:
for(var j = 0; j <=26 ; j++)
{
Debug.Log(first);
Debug.Log(second);
playerOneCards.Add(suffledDeck[first]);
playerTwoCards.Add(suffledDeck[second]);
Debug.Log(playerOneCards[j].img);
Debug.Log(playerTwoCards[j].img);
first += 2;
second += 2;
}

Comparing array to var during iteration(cont.)

So here's my problem.. Might just be tired but, I want counter to ++ only if number has not occurred in array.
Meaning during the 4 iterations, counter should ++ only on iteration 1,3,4
var array = [], number, temp = [4,2,5,9], counter = 0;
for(var i = 0; i <= 3; i += 1) {
array.push(i);
number = temp[i];
}
document.write(counter);
But I'm drawing a blank here... Help?
(No this isn't homework)
if (array.indexOf(number) < 0)
counter++;
unfortunately JS doesn't have an "in_array", but it's pretty straight forward:
#MikeSamuel pointed out you can use indexOf (thanks Mike). So with that being said:
var array = [], number, temp = [4,2,5,9], counter = 0;
for(var i = 0; i <= 3; i += 1) {
array.push(i);
number = temp[i];
if (temp.indexOf(i)==-1) // much simpler, assuming you're checking if i is in temp.
counter++; // increase counter if it is not.
}
document.write(counter);
I'm not sure where you want the logic, so you'll have to figure that out or be more specific. Just know that you need to iterate through the array you're checking and check if the "needle" is in the "haystack" array.
EDIT Had the opposite, just added bool to check for existence.

Categories