I am trying to have the name show up with the score that relates to that name. So if the highest score is 98 I want Joels name to show up in the display where is says name here.
These are all pretty basic operations to perform in JavScript. I hope you find this information helpful.
I've provided detailed explanations for the techniques used in this answer below. All snippets can be run in your browser. Click Run code snippet below to see the results.
// input data
var names = ["Ben", "Joel", "Judy", "Anne"]
var scores = [88, 98, 77, 88]
// this is a common way to sum the numbers in an array
var total = scores.reduce(function(x,y) { return x + y }, 0)
// average = sum of scores / number of scores
var average = total / scores.length
// use Math.max to find the highest score
var highScore = Math.max.apply(null, scores)
// get the name matching the highest score
var highScoreName = names[scores.indexOf(highScore)]
// output the information to the console
// alternative: use innerHTML or something else to print to the DOM
console.log("total: %d", total)
console.log("average: %d", average)
console.log("highest score: %s had %d", highScoreName, highScore)
Summing an array of numbers:
You could use a for
loop or a forEach
but that is for cavemen.
var scores = [88, 98, 77, 88]
var total = 0
for (var i = 0; i < scores.length; i++) {
total = total + scores[i]
}
console.log("total scores: %d", total)
// 351
Once you learn about higher order functions like Array.prototype.reduce you will never go back to the imperative nightmares of your past
var scores = [88, 98, 77, 88]
var total = scores.reduce(function(sum, score) { return sum + score }, 0)
console.log("total scores: %d", total)
// 351
Without smothering you with too many details, the reducing function function(sum, score) { sum + score }
will be called once for each element in our scores
array. The return value of the function will be used as the sum
the next time it is called
iteration sum score return
-----------------------------------------------------------------
#1 0 88 0 + 88 (88)
#2 88 98 88 + 98 (186)
#3 186 77 186 + 77 (263)
#4 263 88 263 + 88 (351) <-- final value
var total = scores.reduce(function(sum, score) { return sum + score }, 0)
// 351
Finding the max number of an array:
Again, we could use neanderthal techniques like this
var max
var scores = [88, 98, 77, 88]
for (var i = 0; i < scores.length; i++) {
if (max === undefined)
max = scores[i]
else if (max < scores[i])
max = scores[i]
}
console.log("max score: %d", max)
// 98
But we're much smarter than that, right? We could reach for Array.prototype.reduce
again but there's an even better way this time.
Math.max will tell us the maximum of the inputs provided
var max = Math.max(1, 5, 9, 3, 10, 6)
console.log('max: %d', max)
// 10
It'd be nice if we could just write Math.max(scores)
to get the value for our highScore
variable, but Math.max only works on numbers, not arrays. To get around this, we can use Function.prototype.apply which applies a function to an array of arguments. This is perfect for our needs
var scores = [88, 98, 77, 88]
// this is the same as writing Math.max(88, 98, 77, 88)
// but .apply allows us to keep the score values in an array
var max = Math.max.apply(null, scores)
console.log("max score: %d", max)
// 98
Linking the high score to the corresponding name:
Once we have the highScore
value, we have to find the name of the person that matches that score. All we have to do is fine the index of the highScore
value in the scores
array, then look-up the value from the names
array with that same index.
Because the highScore
value is a known value from the scores
array, we can use Array.prototype.indexOf with the guarantee that a valid index will be returned.
var scores = [88, 98, 77, 88]
var highScore = Math.max.apply(null, scores)
var highScoreIndex = scores.indexOf(highScore)
console.log("highScore: %d, highScoreIndex: %d", highScore, highScoreIndex)
// highScore: 98, highScoreIndex: 1
We see highScoreIndex: 1
because array indexes start with 0 and count up. An array index of 1
actually refers to the second element in the array.
So now all we have to do is look up the name using index 1
to get the corresponding name value
var names = ["Ben", "Joel", "Judy", "Anne"]
var scores = [88, 98, 77, 88]
var highScore = Math.max.apply(null, scores)
var highScoreIndex = scores.indexOf(highScore)
var highScoreName = names[highScoreIndex]
console.log("high score of %d by %s", highScore, highScoreName)
// high score of 98 by Joel
Try it :
<html>
<head>
<style>
</style>
</head>
<body>
<p id="results"></p>
<button id="display_results">Show</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script>
var names = ["Ben", "Joel", "Judy", "Anne"];
var scores = [88, 98, 77, 88];
var average;
var total = 0;
var highestScore = 0;
var hightName = "";
function displayResults () {
for (var i = 0; i < scores.length; i++) {
total = total + scores[i]; //both are numbers so adds
if (scores[i] > highestScore) {
highestScore = scores[i];
hightName = names[i];
}
}
//then calculate the average and display
average = parseInt(total/scores.length);
document.getElementById("results").innerHTML = ("\nAverage score is " + average + "\n High score = " + hightName + " with a score of " + highestScore);
};
//$("add").onclick = addScore;
$(document).ready(function(){
$("#display_results").click(function(){
displayResults();
})
})
</script>
</body>
</html>
else {
names[names.length] = nameInput;
convert to numbers
scoreInput = Number(scoreInput);
scores[scores.length] = scoreInput;
and
//then calculate the average and highest score
var displayResults = function () {
Reset total
total = 0;
for (var i = 0; i < scores.length; i++) {
total = total + scores[i];
if (scores[i] > highestScore) {
highestScore = scores[i];
name = names[i];
As names
and scores
arrays have same .length
, you can use same i
variable to select item within names
array as is used to select item in scores
.
Declare name
variable
var name = "";
set name
variable
if (scores[i] > highestScore) {
highestScore = scores[i];
name = names[i];
}
display name
variable
document.getElementById("results")
.innerHTML = "\nAverage score is "
+ average
+ "\nHigh score = "
+ name
+ " here with a score of "
+ highestScore;
You have the i value (the positioning of the score in scores array). This i value corresponds with the person in the persons array. Use this i value to select the person.
To make stuff easier you could use an object to associate name (string) with score (int) like:
var test = {"Ben": 88, "Joel": 98, "Judy": 77, "Anne": 88}
Then you would need to modify the for loop.
You can store the index instead of the highest score and use it to get the name. I have changed your code to support it and added comment 'Changes' to wherever the changes are,
var names = ["Ben", "Joel", "Judy", "Anne"];
var scores = [88, 98, 77, 88];
var average;
var total = 0;
var highScoreIndex = 0;// Changes
var $ = function (id) { return document.getElementById(id); };
var displayResults = function () {
for (var i = 0; i < scores.length; i++) {
total = total + scores[i]; //both are numbers so adds
if (scores[i] > highestScore) {
highestScoreIndex = i; // Changes
}
}
//then calculate the average and display
average = parseInt(total/scores.length);
document.getElementById("results_header").innerHTML =
("Results");
document.getElementById("results").innerHTML = ("\nAverage score
is " + average + "\nHigh score = " + names[highestScoreIndex] + " with a score of " +
scores[highestScoreIndex]); //Changes
};
window.onload = function () {
//$("add").onclick = addScore;
$("display_results").onclick = displayResults;
//$("display_scores").onclick = displayScores;
};