Updating a multidimensional array using two 'for' loops - javascript

I'm seeking to update the a league table by looping through a results array by player. The user populates the results through a html table beforehand.
players=[];
var players=["A","B","C"];
Results=[];
var Results=[
["Home","F","A","Away"],
["A",,,"B"],
["A",,,"C"],
["B",,,"C"],
["B",,,"A"],
["C",,,"A"],
["C",,,"B"],
];
League=[];
var League=[
["Team","P","W","D","L","F","A","Pts"],
["A",,,,,,,],
["B",,,,,,,],
["C",,,,,,,]
];
I've tried using two for loops as follows:
var pld=0;
var wins=0;
var draws=0;
var loses=0;
var goalsF=0;
var goalsA=0;
var pts=0;
for (p = 0; p <= players.length; p++)
{
for (i = 1; i < Results.length; i++)
{
if (Results[i][1]!= "")
{
if (Results[i][0]==players[p])
{
pld++;
if (Results[i][1]>Results[i][2])
{
wins++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
pts= +pts + 3;
}
else if (Results[i][1]<Results[i][2])
{
loses++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
}
else
{
draws++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
pts++
}
}
}
}
League[p][1]=pld;
League[p][2]=wins;
League[p][3]=draws;
League[p][4]=loses;
League[p][5]=goalsF;
League[p][6]=goalsA;
League[p][7]=pts;
}
Where the first two results are input, A's table values are correct but they're wrongly showing for B and C?
And when all six results are keyed on, again A's values are correct but B's and C's just accumulate?
I believe my problem is related to where I'm resetting the win, draws and losses etc counts. If I do this before the for loops (as shown above), results get counted twice, if I do this inside, nothing is counted at all.
Any guidance appreciated. Thanks!

Thanks to everyone's resposnse so far, I managed to find a solution - I reset the count variables immediately after updating the league but is there a better solution?
var pld=0;
var wins=0;
var draws=0;
var loses=0;
var goalsF=0;
var goalsA=0;
var pts=0;
for (p = 0; p <= players.length; p++)
{
for (i = 1; i < Results.length; i++)
{
if (Results[i][1]!= "")
{
if (Results[i][0]==players[p])
{
pld++;
if (Results[i][1]>Results[i][2])
{
wins++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
pts= +pts + 3;
}
else if (Results[i][1]<Results[i][2])
{
loses++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
}
else
{
draws++;
goalsF=+goalsF + +Results[i][1];
goalsA=+goalsA + +Results[i][2];
pts++
}
}
}
}
League[p][1]=pld;
League[p][2]=wins;
League[p][3]=draws;
League[p][4]=loses;
League[p][5]=goalsF;
League[p][6]=goalsA;
League[p][7]=pts;
// Reset the 'count' variables here:
var pld=0;
var wins=0;
var draws=0;
var loses=0;
var goalsF=0;
var goalsA=0;
var pts=0;**
}

Related

Efficient Table Seating Function

I'm creating a table seating function in javascript, directly below, for a scenario where there is a population of P participants, in this case tested with 80, and S seats per table, in this case tested by 8, each participant may only visit each table once with a total of ten tables and each participant may not meet another participant more than once for a minimum of 10 rotations.
How can I make 10 unique sets of P/S, 10 times?
To explain my naming, arrayArray is the array for each of the tables and the outer arrays inner array elements are the table seating, arrayArrayPrevious is the list of everyone whose already been to a table, and the participantArray is an array of all possible participants.
The trouble seems to be when finding two participants have already met and moving the second one to the end of the participantArray to be tried again later results in only one participant ever being placed.
I'm placing the entire code below the function snippet in the event someone can help solve it and its useful for others in the future.
function notMetAlready(w, arrayArray, participantAlreadyMet){
if(arrayArray.includes(participantAlreadyMet)){
var moveToEnd = arrayArray[w][0];
console.log(moveToEnd);
participantArray.push(moveToEnd);
console.log(participantArray);
return true;
//console.log(index);
}
if(!arrayArray.includes(participantAlreadyMet)){
return true;
}
else{
return false;
}
}
Full Code
<html>
<head>
<script type="text/javascript">
var tables = 10;
var participants = 80;
var participantPool = [];
var seatingPerTable = participants/tables;
var arrayArray = new Array(tables);
for(var i = 1; i <= participants; i++){
participantPool.push(i);
}
var count = 1;
var participantArray = new Array(participants);
var participantAlreadyMet = new Array(participants);
var arrayArrayPrevious = new Array(tables);
for (var i = 0; i <= tables; i++) {
arrayArrayPrevious[i] = [];
arrayArray[i] = [];
}
for (var i = i; i < participantAlreadyMet.length; i++) {
participantAlreadyMet[i] = [i];
}
function MatchingPairs() {
for (var i = 0; i < tables; i++) {
arrayArray[i] = [];
}
for(var h = 0; h < participants; h++){
participantArray[i] = i+1;
}
for(var w = 0; w < arrayArray.length; w++){
if(tablesHaveNotIncluded(w,0)){
// for(var n = 1; n < participants; n++){
do{
if(tablesDoNotInclude(0) && notMetAlready(w, arrayArray[w], participantAlreadyMet[0])){
arrayArray[w].push(participantArray[0]);
arrayArrayPrevious[w].push(participantArray[0]);
participantArray.shift();
}
}while(participantArray >= 0);
}
}
function notMetAlready(w, arrayArray, participantAlreadyMet){
if(arrayArray.includes(participantAlreadyMet)){
var moveToEnd = arrayArray[w][0];
console.log(moveToEnd);
participantArray.push(moveToEnd);
console.log(participantArray);
return true;
}
if(!arrayArray.includes(participantAlreadyMet)){
return true;
}
else{
return false;
}
}
for(var z = 0; z < tables; z++){
var plus = z + 1;
console.log("Table " + plus + " " + arrayArray[z] );
}
console.log("Rotation " + count);
count++;
function tablesHaveNotIncluded(w,n){
var outerArray = arrayArrayPrevious[w];
if(!outerArray.includes(n)){
return true;
}
return false;
}
function tablesDoNotInclude(n){
for(var w = 0; w < tables; w++){
if(!arrayArray[w].includes(n)){
return true;
}
}
return false;
}
}
</script>
</head>
<body>
<button onclick="MatchingPairs()">Combinations</button>
</body>
</html>

JS for loop not working

I have a for loop which looks like this:
for (var i = 0; i < list.length; i++) {
It is looping through Firebase data in the database and returning all the data in the database.
However, I want it to only go up to the first 10 database items. So I changed the loop to:
for (var i = 0; i < 9; i++) {
But this fails to display any results when the there are less than 10 pieces of data in the database. However, if I set the number to however many objects I have in the database, for example 10 because I have 10 objects, it displays them all. But any less than this number and I just get a blank webpage.
Here is the webpage when I have 10 objects in my Firebase database:
And here it is when I remove one of those objects:
I have no idea why this is happening - The logic is correct - if i is less than 9 then display the data - But instead it only displays it when it equals 9.
Here is the full JS:
function refreshUI(list) {
var lis = '';
var lis2 = '';
var lis3 = '';
var lis4 = '';
for (var i = 0; i <= 9; i++) {
lis += '<li data-key="' + list[i].key + '" onclick="addText(event)">' + list[i].book + '</li>';
lis2 += genLinks(list[i].key, list[i].book)
};
for (var i = 10; i < list.length; i++) {
lis3 += '<li data-key="' + list[i].key + '" onclick="addText(event)">' + list[i].book + '</li>';
lis4 += genLinks(list[i].key, list[i].book)
};
document.getElementById('bookList').innerHTML = lis;
document.getElementById('bookList2').innerHTML = lis2;
document.getElementById('bookList3').innerHTML = lis3;
document.getElementById('bookList4').innerHTML = lis4;
};
function genLinks(key, bkName) {
var links = '';
links += '<img src="images/bin.png" style="width: 24px; height: 24px; transform: translateY(-7px); opacity: .4;"></img> ';
return links;
};
function del(key, bkName) {
var response = confirm("Are certain about removing \"" + bkName + "\" from the list?");
if (response == true) {
// build the FB endpoint to the item in movies collection
var deleteBookRef = buildEndPoint(key);
deleteBookRef.remove();
}
}
function buildEndPoint (key) {
return new Firebase('https://project04-167712.firebaseio.com/books/' + key);
}
// this will get fired on inital load as well as when ever there is a change in the data
bookList.on("value", function(snapshot) {
var data = snapshot.val();
var list = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
book = data[key].book ? data[key].book : '';
if (book.trim().length > 0) {
list.push({
book: book,
key: key
})
}
}
}
// refresh the UI
refreshUI(list);
});
If anybody has any help I'd greatly appreciate it!
When the list size is shorter than 10, you will get an error in the loop because you will eventually address a property (like key) that does not exist on list[i] (since it is undefined). If you would check the console, you would notice that this error is reported.
To fix this, change the condition of the first for loop like this:
for (var i = 0; i < Math.min(10, list.length); i++) {
This way, the loop will never iterate to an entry that does not exist. It will stop after 9 or after list.length-1 whichever comes first.
Alternatively, you can just put the two conditions with an && operator:
for (var i = 0; i < 10 && i < list.length; i++) {

Simple Quiz Game JavaScript

I'm just learning now. Can you please help me, why am I not getting the correct output. This is my code:
//ask questions
var quiz = [
["When is Bulgaria established?", 681],
["What year was it before 16 years?", 2000],
["When does WWII ends?", 1945]
];
//variables
var answer = [];
var correct = [];
var wrong = [];
var correctAns = 0;
var wrongAns = 0;
var oList = "<ol>";
//function to print the result in ordered list
function printResult(result){
for(var j = 0; j < result.length; j++){
oList += "<li>" + result[i] + "</li>";
}
oList += "</ol>";
return oList;
}
function print(message) {
document.getElementById('output').innerHTML = message;
}
//looping, adding correct and wrong answeres
for(var i = 0; i < 3; i++) {
answer[i] = prompt(quiz[i][0]);
if(parseInt(answer[i]) == quiz[i][1]){
correct.push(quiz[i][0]);
correctAns++;
} else {
wrong.push(quiz[i][0]);
wrongAns++;
}
}
//print logic
if(correct.length < 1 || correct == undefined){
print("You did not guess any of the quiestions!");
} else if (correct.length >= 1){
print("You have guessed " + correctAns + " questions.");
print(printResult(correct));
print("You have " + wrongAns + " wrong answeres.");
if(wrongAns > 0){
print(printResult(wrong));
}
}
I have watched this code over and over again and I still can't understand why am I getting undefined as a result. In the debugger, after the loop I check my vars and everything seems ok.
In your printResult function you are using var i instead of j,
Also you better use innerHtml+=message;
//ask questions
var quiz = [
["When is Bulgaria established?", 681],
["What year was it before 16 years?", 2000],
["When does WWII ends?", 1945]
];
//variables
var answer = [];
var correct = [];
var wrong = [];
var correctAns = 0;
var wrongAns = 0;
//function to print the result in ordered list
function printResult(result){
//HERE:
var oList = "<ol>";
for(var j = 0; j < result.length; j++){
oList += "<li>" + result[j] + "</li>";
}
oList += "</ol>";
return oList;
}
function print(message) {
document.getElementById('output').innerHTML += message;
}
//looping, adding correct and wrong answeres
for(var i = 0; i < 3; i++) {
answer[i] = prompt(quiz[i][0]);
if(parseInt(answer[i]) == quiz[i][1]){
correct.push(quiz[i][0]);
correctAns++;
} else {
wrong.push(quiz[i][0]);
wrongAns++;
}
}
//print logic
if(correct.length < 1 || correct == undefined){
print("You did not guess any of the quiestions!");
} else if (correct.length >= 1){
print("You have guessed " + correctAns + " questions.");
print(printResult(correct));
print("You have " + wrongAns + " wrong answeres.");
if(wrongAns > 0){
print(printResult(wrong));
}
}
<div id="output">
</div>
Basically you have three problems.
reuse of oList, the variable should be inside declared and used only in printResult.
Inside of printResult, use of i where j have been used and
At print, you replace the actual content with new content.
Just a small hint with variable names for counting. It is good practise to start always with i instead of j and go on with the letters in the alphabet.
var quiz = [["When is Bulgaria established?", 681], ["What year was it before 16 years?", 2000], ["When does WWII ends?", 1945]],
answer = [],
correct = [],
wrong = [],
correctAns = 0,
wrongAns = 0;
//function to print the result in ordered list
function printResult(result) {
var oList = "<ol>"; // !!! move variable inside of the function
for (var j = 0; j < result.length; j++) {
oList += "<li>" + result[j] + "</li>"; // !!! use j indstead if i
}
oList += "</ol>";
return oList;
}
function print(message) {
document.getElementById('output').innerHTML += message; // !!! append message
}
//looping, adding correct and wrong answeres
for (var i = 0; i < 3; i++) {
answer[i] = prompt(quiz[i][0]);
if (parseInt(answer[i]) == quiz[i][1]) {
correct.push(quiz[i][0]);
correctAns++;
} else {
wrong.push(quiz[i][0]);
wrongAns++;
}
}
//print logic
if (correct.length < 1 || correct == undefined) {
print("You did not guess any of the quiestions!");
} else if (correct.length >= 1) {
print("You have guessed " + correctAns + " questions.");
print(printResult(correct));
print("You have " + wrongAns + " wrong answeres.");
if (wrongAns > 0) {
print(printResult(wrong));
}
}
Your main mistake is using i intead of j:
for(var j = 0; j < result.length; j++){
oList += "<li>" + result[j] + "</li>";// here was i before
}

How to count the number of section tags in an article tag?

I have been trying to write code that would use an embedded for loop to calculate the number of sections inside of each article (there is more than one so I can't use getID) in a document. When the button is clicked the code works but the numbers it calculates are completely off which means something isn't counting correctly. Here is my function:
<script>
function Calculations() {
var a = document.getElementsByTagName("article");
var s = 0;
var z = 0;
var x;
for (x = 0; x < a.length; x++) {
var cn = a[x].childNodes;
z++
for (i = 0; i < cn.length; i++) {
if (cn[i].nodeType == 1) {
if (cn[i].tagName == "P"); {
s++;
}
}
}
alert("Article " + z + " has " + s + " section.")
s = 0
}
alert("There are " + a.length + " total articles.")
}
</script>
Thank you so much for your help!

two delimiters output formatting javascript

I thought this would be easier, but running into a weird issue.
I want to split the following:
theList = 'firstword:subwordone;subwordtwo;subwordthree;secondword:subwordone;thirdword:subwordone;subwordtwo;';
and have the output be
firstword
subwordone
subwordtwo
subwordthree
secondword
subwordone
thirdword
subwordone
subwordtwo
The caveat is sometimes the list can be
theList = 'subwordone;subwordtwo;subwordthree;subwordfour;'
ie no ':' substrings to print out, and that would look like just
subwordone
subwordtwo
subwordthree
subwordfour
I have tried variations of the following base function, trying recursion, but either get into infinite loops, or undefined output.
function getUl(theList, splitOn){
var r = '<ul>';
var items = theList.split(splitOn);
for(var li in items){
r += ('<li>'+items[li]+'</li>');
}
r += '</ul>';
return r;
}
The above function is just my starting point and obviously doesnt work, just wanted to show what path I am going down, and to be shown the correct path, if this is totally off base.
It seems you need two cases, and the difference between the two is whether there is a : in your string.
if(theList.indexOf(':') == -1){
//Handle the no sublist case
} else {
//Handle the sublist case
}
Starting with the no sublist case, we develop the simple pattern:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
//Add your element to your list
}
Finally, we apply that same pattern to come up with the implementation for the sublist case:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(element.indexOf(':') == -1){
//Add your simple element to your list
} else {
var innerElements = element.split(':');
//Add innerElements[0] as your parent element
//Add innerElements[1] as your child element
//Increment i until you hit another element with ':', adding the single elements each increment as child elements.
//Decrement i so it considers the element with the ':' as a parent element.
}
}
Keep track of the current list to add items to, and create a new list when you find a colon in an item:
var baseParent = $('ul'), parent = baseParent;
$.each(theList.split(';'), function(i, e) {
if (e.length) {
var p = e.split(':');
if (p.length > 1) {
baseParent.append($('<li>').append($('<span>').text(p[0])).append(parent = $('<ul>')));
}
parent.append($('<li>').text(p[p.length - 1]));
}
});
Demo: http://jsfiddle.net/Guffa/eWQpR/
Demo for "1;2;3;4;": http://jsfiddle.net/Guffa/eWQpR/2/
There's probably a more elegant solution but this does the trick. (See edit below)
function showLists(text) {
// Build the lists
var lists = {'': []};
for(var i = 0, listKey = ''; i < text.length; i += 2) {
if(text[i + 1] == ':') {
listKey = text[i];
lists[listKey] = [];
} else {
lists[listKey].push(text[i]);
}
}
// Show the lists
for(var listName in lists) {
if(listName) console.log(listName);
for(var j in lists[listName]) {
console.log((listName ? ' ' : '') + lists[listName][j]);
}
}
}
EDIT
Another interesting approach you could take would be to start by breaking it up into sections (assuming text equals one of the examples you gave):
var lists = text.match(/([\w]:)?([\w];)+/g);
Then you have broken down the problem into simpler segments
for(var i = 0; i < lists.length; i++) {
var listParts = lists[i].split(':');
if(listParts.length == 1) {
console.log(listParts[0].split(';').join("\n"));
} else {
console.log(listParts[0]);
console.log(' ' + listParts[1].split(';').join("\n "));
}
}
The following snippet displays the list depending on your requirements
var str = 'subwordone;subwordtwo;subwordthree;';
var a = []; var arr = [];
a = str;
var final = [];
function split_string(a){
var no_colon = true;
for(var i = 0; i < a.length; i++){
if(a[i] == ':'){
no_colon = false;
var temp;
var index = a[i-1];
var rest = a.substring(i+1);
final[index] = split_string(rest);
return a.substring(0, i-2);
}
}
if(no_colon) return a;
}
function display_list(element, index, array) {
$('#results ul').append('<li>'+element+'</li>');
}
var no_colon_string = split_string(a).split(';');
if(no_colon_string){
$('#results').append('<ul><ul>');
}
no_colon_string.forEach(display_list);
console.log(final);
working fiddle here

Categories