I am trying to dynamically access arrays, otherwise I would have to duplicate my code, when in reality the only difference would be buildablesets1 and buildablesets2.
var buildablesets1 = [""];
var buildablesets2 = [""];
var buildablesetsx = "buildablesets" + playerturn;
for (var i = 0; i < set.length; i++) {
if (doesOwnSet('player'+playerturn, set[i])) {
if(playerturn===1) buildablesets1.push(set[i]);
}
}
if (buildablesetsx.length > 1){
var b = $("#buildsets"+playerturn);
for (k = 1; k < buildablesetsx.length; k++){
b.append("<option value='" + buildablesetsx[k]+ "'>" + buildablesetsx[k] + "</option>");
}
}
The code pushes any sets owned by the player to buildablesetsX. Then the dropdown box #buildsetsX is populated with all the owned sets.
1. How do I get the effect of buildablesetsX where X depends on the players turn.
2. I want to depopulate the dropdown box on each turn otherwise it will duplicate, since it is appending. (would apreciate a better way of doing this, ideally I want to populate the dropdown box only if there is a new set).
Plus sorry I understand that this question has been asked before, but I didnt understand the answers or the question exactly.
Any time you find yourself creating variables with sequential numbers, and wanting to access them dynamically, what you really should be using is an array. In this case, you should use a two-dimensional array:
var buildablesets = [[""], [""]];
The first dimension is the player number, the second dimension is the list of sets that player has built.
To access a particular player's sets, do:
buildablesetsx = buildablesets[playerturn];
The rest of your code will work as you've written it, with the above variable assignment.
Related
I'm new to javascript so any help would be greatly appreciated.
What I'm trying to do is cycle through every element in the array and count the number of times the value of an element matches a given condition (even if the value is duplicated).
function loaddata(xml) {
var count = 0;
var i;
var xmlDoc = xml.responseXML;
var z = xmlDoc.getElementsByTagName("group");
if (value1 <= value2) {
for (i = 0; i < (0 + z.length); i++) {
if (z[i].getElementsByTagName("name")[0].childNodes[0].nodeValue == "John") {
count++;
}
}
}
$('#count1').html(count);
};
The count value outputted is too small. I believe the reason for this that the for loop isn't iterating through all elements in the array. When I remove the second if loop and output the count for just the for loop this value is also too small. I believe that the for loop isn't searching through the duplicate elements of the array (i.e. it is ignoring them so that they aren't then fed into the second if loop). Is it possible to specify that the for loop include duplicates?
Do a console.log(z[i].getElementsByTagName("name")) and open your browser's console, and see if that array has data in it.
Then console.log(z[i].getElementsByTagName("name")[0].childNodes) and make sure you have nodes in it.
Also, do you have many <group></group> tags? Because that's what you are selecting with var z = xmlDoc.getElementsByTagName("group");
I hope that helps,
http://eloquentjavascript.net/04_data.html
Please. Scroll down to the headline "The lycanthrope’s log" . It introduces the phi correlation which took me a while to understand, If you scroll down a little bit further, You will find the headline Computing correlation.
var journal = [];
function addEntry(events, didITurnIntoASquirrel) {
journal.push({
events: events,
squirrel: didITurnIntoASquirrel
});
}
function phi(table) {
return (table[3] * table[0] - table[2] * table[1]) /
Math.sqrt((table[2] + table[3]) *
(table[0] + table[1]) *
(table[1] + table[3]) *
(table[0] + table[2]));
}
Top^^^^The code that is also part of the full "program". I've put my "QUESTIONS" in comments in the code below. Please help! If anyone can also answer the comments in my question i will be VERY GRATEFUL!!!!!
function hasEvent(event, entry) {
return entry.events.indexOf(event) != -1;
/*What does "events" do?Why -1?How does indexOf work?"*/
}
function tableFor(event, journal) {
var table = [0, 0, 0, 0];
/*How does the program figure out each of the values for this table?*/
/*and how does it know when one value ends and the time to start*/
/*calculating the next value*/
for (var i = 0; i < journal.length; i++) {
var entry = journal[i], index = 0;/*???? why 0*/
if (hasEvent(event, entry)) index += 1;
/*I dont understand how this function works*/
if (entry.squirrel) index += 2;/*why +2?*/
table[index] += 1;/*what exactly is index???*/
}
return table;
}
I'm really new to teaching myself programming. Eloquent javascript is supposed to be for beginners and i'm already struggling :\
indexOf is a method available on Strings and Arrays in Javascript. You can use it to find something in either one of the objects. It returns -1 if it doesn't find the thing you're looking for in the String or Array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
return entry.events.indexOf(event) != -1; Is trying to figure out if the event you're asking about, exists within the array of events for a given entry by checking the return value of indexOf. This is a common Javascript idiom.
var entry = journal[i], index = 0;/*???? why 0*/
this assigns a reference to value from journal[i] into the entry variable. It also assigns the integer value 0 the index variable.
This multiple variables being defined on a single line. How to define multiple variables on a single line?
This is an if statement that only executes the code directly following it. This is terrible, but valid, syntax. You should never do this in real life. Always use braces. if (hasEvent(event, entry)) index += 1;
Are curly braces necessary in one-line statements in JavaScript?
I've transformed the code you posted into something more readable by getting rid of all the syntactic junk the author put in there. My only guess with table is that it's trying to record all the different possible outcomes from the ifs here. You get 0 if there's no event, and there's no squirrel. You get 1 if there's an event but no squirrel. You get 2 if there's no event, but there is a squirrel. And you get 3 if there is an event, and a squirrel. You then increment one of four different positions in the table variable based on what transpired.
Since you're iterating over a journal with i, my assumption is that you're trying to keep track of what's happening to you over a long period of time. So if you had, 1 journal entry that added up to 10 and 5 journal entries that added up to 1, and 3 journal entries that added up to 2, then you'd have a table variable with [10, 5, 2, 0] in it.
You can basically think of index as keeping track of all possible states. If there were a third possibility, such as "there is a shark", and it could be independently true or false like the other ones, the index could have a total possible value of 7 (1 + 2 + 4) because the shark one would have to add 4 to index to not step on the toes of the previous two. This is related to the sum of the powers of two SUM (2^n) where n is the number independently possible different things that could happen to you.
for (var i = 0; i < journal.length; i++) {
var entry = journal[i];
var index = 0;
if (hasEvent(event, entry)) {
index += 1;
}
if (entry.squirrel) {
index += 2;
}
table[index] += 1;
}
Generally if you're going to get into programming you need to learn to Google this stuff for yourself. It can be difficult at first, but it is an invaluable skill to learn. I'd rather hire a novice developer that could Google his way out of a problem then an intermediate developer who couldn't reliably find answers on Google.
I am working on a JS where I want to create a simple game that starts by chosing number of players, name of each player and whether a player is a dealer or not. There can be only one dealer for each game:
function player(playerName, playerDealer) {
this.playerName = playerName;
this.playerDealer = playerDealer;
}
var playerNumber = prompt('Nr of players?');
var playersArray = [];
for (i = 0; i < playerNumber; i++) {
var j = i + 1;
var dealerAssigned = false; // control variable to check whether dealer has been assigned
var inputName = prompt('Name of player nr ' + j);
var inputDealer = prompt('Is player ' + inputName + ' also a dealer? (yes/no)');
playersArray[i] = new player(inputName, inputDealer);
for (k=0;k<playerNumber;k++){ // I want to go through the players array to check if dealer has been assigned
if (playersArray[k].playerDealer == 'yes') {
dealerAssigned=true;
break;
};
};
if(dealerAssigned){ //if dealer has been assigned, don't add the current player to the array and continue with the next iteration
alert("already assigned");
continue;
};
};
I need to include a simple test into the loop that would check if the dealer has been appointed. If so, I want the script only to alert 'already assigned' and skip to the next player. But I am constantly getting the following error
TypeError: playersArray[k] is undefined
Can anybody explain why is it undefined?/What am I doing wrong?
The bug you're specifically asking about appears to me to be that you're iterating over undefined array values, as the error you're getting suggests.
You're getting the number of players you want in line
var playerNumber = prompt('Nr of players?');
Then, you proceed to have two iterations (one nested in the other), in which the inner loop is trying to access values that haven't yet been assigned since the outer loop hasn't gotten there yet:
for (i = 0; i < playerNumber; i++) {
playersArray[i] = new player(inputName, inputDealer);
for (k=0; k < playerNumber; k++) {
if (playersArray[k].playerDealer == 'yes') {
...
}
}
}
It appears to me that the logical error here is the nested loop. I recommend just initializing all players in one loop, then verify that all players have an assigned dealer afterward.
I should add that I'm being intentionally myopic here and focusing very narrowly on the question asked and overlooking other issues I see.
Your for loop inside a for loop is iterating over an array that hasn't been filled yet.
First iteration playersArray[j] = new Player(...) makes the array [Player] or an array of one element! Yet the second loop is looking for an array of many elements. once you look for playersArray[1] but there is only playerArray[0] you get undefined and so undefined.playerDealer causes a TypeError.
`This is your structure stipped-down:
for (i = 0; i < playerNumber; i++) {
playersArray[i] = new player(inputName, inputDealer);
for (k=0;k<playerNumber;k++)...{
//anything with index k > i is undefined, since your outer loop
//hasn't initialized it yet.
}
}
It seems that your i-loop is trying to insert elements for the size of the array to be, but your k-loop is trying to also access the entire array instead of just the initialized portions. Limit this to for (k=0; k<i+1 ;k++) so you only check the previously initialized values of you playersArray
Okay so I have a 2D array that I am trying to alter using javascript. This is what I have so far:
for (var i = 0; i <= inputData.length; i++ {
inputData[0,0] = inputData[0,0];
inputData[i,0] = inputData[((i - 1) + 1/12), 0];
I want this to take array [i-1] value and then add 1/12 to it
for (j = 13; inputData.length; j += 13) {
delete inputData[j,0];
delete inputData[j,1];
}
Also, I want to delete the entire 2D array at every 13th increment value.
}
This is what I have so far. I am sure there are probably errors within it. Can you guys help me out here? Any help would be greatly appreciated.
Couple of things - you need to be careful when iterating over an array that you're removing from, your indexes will end up offset with respect to your data as soon as you do a delete. Secondly your syntax for deletion is off.
Normally in these situations I favour creating a new array containing the data I want to keep.
var inputData = [[1,1],[2,2],[3,3],[4,4]];
var b = [];
for (i=0; i < inputData.length; i++) {
if ((i + 1) % 13 != 0) {
var year_with_month = inputData[i][0] + i * 1/12;
var e = [year_with_month, inputData[i][1]]
b.push(e);
}
}
inputData = b;
Also, given a choice I'd use a library like underscore to make it easy to do the looping. I never manually write for loops anymore, took me a couple of attempts to get that one right :)
I am trying to populate an empty list using an array of photo names. I have made this work already, but with a large amount of photos it can become relatively slow. More than 500 photos is not unusual.
I am wondering if someone could find a way to make this code work faster, or tell me what make this code run slow so I can have another look at it myself.
The code I have is as follows. this.photoListElement is a jQuery object referring to the unordered list element. photoNames is an array of photo name strings. Variables are declared at the top of the function which is not shown here. isThumbDownloaded checks a variable in an object. getThumb and getThumbId are functions which add some strings together.
(...)
place = [];
for(i=0; i< photoNames.length; ++i) {
photoName = photoNames[i];
if(coverages.isThumbDownloaded(coverageId, photoName)){ // A function which checks if a photo is downloaded. If it is, the photo should not be hidden, and the right background should be applied.
bg = 'background-image:url(\''+coverages.getThumb(coverageId, photoName) + '?' + new Date().getTime()+'\');';
cls = '';
} else {
bg = '';
cls = 'hidden';
}
place[i] = '<div id="'+ this.getThumbId(photoName) +'" photoName="'+photoName+'" style="'+bg+'" class="phoPhoto '+cls+'" onclick="$.mobile.changePage($(\'#carousel\'), {transition: \'slidefade\'})"></div>';
}
this.photoListElement.html(place.join(''));
(...)
Help is very much appreciated.
After research
The problem is not the loop, although some minor optimizations can be done, but the the dom insertion.
In the loop you are counting the number of photoNames on each iteration:
for(i=0; i< photoNames.length; ++i)
Keep the length in a variable instead and the loop will be faster:
for (var i = 0, ilen = photoNames.length; i < ilen; i += 1)
Also, string concatenation might be faster than array join, check this jsperf .
So:
place = "";
...
place += '<div>.......';
..
this.photoListElement.html(place);
Try using
$('ul').append(ilen);