Reputation: 105
I am trying to sum a dynamic array. But for some reason the numbers aren't adding up, but just displayed next to each other. I am trying to do 1+2+3+4+5. but my output ends up being 012345 instead of 15.
var userInput = -1;
var totalinputs = [];
var sum = 0;
var j = 0;
While(userInput != 999)
{
userInput = window.prompt("Enter a test score, or 999 to end the program");
if(userInput <= 100 && userInput >= 0)
{
totalInputs[j] = userInput;
j++;
}
}
$("lastScore").value = totalInputs[j-1];
for(var i = 0; i < totalInputs.length; i++)
{
sum += totalInputs[i];
}
$("sumScores").value = sum;
So when the prompt appears I enter 1,2,3,4,5 while pressing enter in between each input, then I enter 999 to end the prompt. The output comes out as 012345 instead of 15. I have tried multiple options but am not sure why it is doing that. The $ function just returns
window.document.getElementById(theId);
Upvotes: 1
Views: 1390
Reputation: 2535
Although you already mark one as an answer but I'll try to throw my own version. Both answers above will only work in some cases. It's prune to bug why? Because you can't trust user's input.
@Luis's answer is good, but have you tried inputting alphanumeric like 1bs64s
? You'll find that after parsing it return number 1. Your user didn't expect that probably but if that's okay with you I think "I'll stop here" but in user's perspective it might be weird because you allow to add alphanumeric.
Below are the description why it happen if you are curios.
If parseInt encounters a character that is not a numeral in the specified radix, it ignores it and all succeeding characters and returns the integer value parsed up to that point. parseInt truncates numbers to integer values. Leading and trailing spaces are allowed.
Well, after you read that you'll probably say, that's easy lets just put the radix
base of 10 to solve the problem. No, it didn't. Since the program accept a range of number from 0-100 @Programmer's program will still accept it.
@Pbd's answer has issue too and suffer same faith described above. He just simply coercing string to number without proper validation.
// this condition without properly validation returns true. Allowing `1e1` to store in array.
if("1e1" <= 100 && "1e1" >= 0) // is true!
upon summing up the output is different(dynamic typing).
var sum = 0;
sum += totalInputs[i] // assuming totalInputs[i] returns `1e1`
console.log(sum); // the output is "01e1".
There are probably many versions for validation to keep you safe but IMHO is to trim user's input, coerces string to number and validate if input is convertible into integer.
userInput = window.prompt("Enter a test score, or 999 to end the program").trim(); // or userInput = userInput.trim();
var convertedInput = +userInput;
var isNumber = convertedInput == userInput; // check equality "1" == 1
if(userInput && isNumber && convertedInput >= 0 && convertedInput <= 100)
totalInputs[j] = convertedInput;
In addition to simplify summation use reduce.
var sum = totalInputs.reduce(function(pv, cv) { return pv + cv; }, 0);
or with arrow functions introduced in ES6, it's even simpler:
var sum = totalInputs.reduce((pv, cv) => pv+cv, 0);
Credit goes to @Chaos's answer. I haven't check reduce cross browser perf.
Javascript is fun! :)
Upvotes: 1
Reputation: 58
First of all, you have a lot of typos in that script, and it was really difficult to make it work.
Ok, let's go: when you prompt something, the browser stores the result in as a string. If you sum the string index 0 with the string index 1, you'll get the concatenation of both, not the sum (as you expect). To fix this, you can use the parseInt function.
var userInput = -1;
var totalInputs = [];
var sum = 0;
var j = 0;
while(userInput != 999)
{
userInput = window.prompt("Enter a test score, or 999 to end the program");
if(userInput <= 100 && userInput >= 0)
{
totalInputs[j] = userInput;
j++;
}
}
$("lastScore").value = totalInputs[j-1];
for(var i = 0; i < totalInputs.length; i++)
{
sum += parseInt(totalInputs[i]);
}
$("sumScores").value = sum;
And that will work as expected. Look at the statement inside the for loop. ParseInt. Cast the string to an Integer, and then sum it.
To make it even better, you could store an Int, not cast it when adding to the sum. So you'd like to change this:
userInput = window.prompt("Enter a test score, or 999 to end the program");
To this:
userInput = parseInt(window.prompt("Enter a test score, or 999 to end the program"));
And then you could remove the parseInt from the for loop. Finally:
// sum += parseInt(totalInputs[i]);
sum += totalInputs[i];
Upvotes: 2
Reputation: 1319
Replace with following
for(var i = 0; i < totalInputs.length; i++)
{
sum += +totalInputs[i]; //this coerces string to number.
}
a = "1"
can be converted to a = 1
in javascript by just writing a = +a, This type of coercion is a JS feature.
The user input from the prompt box is a string. Hence you are facing this issue.
Upvotes: 3