How can I calculate the number within a string? [duplicate] - javascript

This question already has answers here:
How do you test for NaN in JavaScript?
(3 answers)
Closed 2 years ago.
my code is like that..
i m using isNaN() but problem is still valid
function numberSearch (str) {
let sum = 0;
let strCount = 0;
if(str === "") {
return 0;
};
for(let i = 0 ; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
}
sum = sum + Number(str[i])
}
return Math.round(sum/strCount);
}
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
How can I count the number and calculate it?
I'm using isNaN(), but when i using debugger sum is 'NaN'
I cant treat well.. i cant understand well..

Scroll for answer to edited question.
NaN === NaN
will be false, there is a good explanation given here.
Try using isNaN() for your check instead of comparison.
Edit: As far I understood you, you want to get a rounded average of the numbers found within the string. The if check is modified accordingly -- it has to increase count and sum, if there is a number being checked:
function numberSearch (str) {
let sum = 0;
let count = 0;
if (str === '') {
return 0;
};
for (let i = 0 ; i < str.length ; i++) {
// if character is not empty and is a number,
// increase count and sum
if (str[i] !== ' ' && !isNaN(Number(str[i]))) {
count++;
sum = sum + Number(str[i]);
}
}
return Math.round(sum/count);
}
let output = numberSearch('Hello6 ');
console.log(output); // 6 now, 6 / 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 6 now, 17 / 3

Related

Add individual negative numbers from a String

function sumDigits(num) {
newStr = num.toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return sum;
}
var output = sumDigits(1148);
console.log(output); // --> 14
Hey guys, my output is 14. However, my for loop falls apart if num is a negative number. Anyone got any ideas how to get past this? Presently, a negative number returns 'NaN'
I would suggest using a modulus approach here, which avoids the unnecessary cast from integer to string and vice-versa:
function sumDigits(num) {
var sum = 0;
while (num != 0) {
sum += num % 10;
num = num > 0 ? Math.floor(num / 10) : Math.ceil(num / 10);
}
return sum;
}
var output = sumDigits(1148);
console.log("1148 => " + output);
var output = sumDigits(-1148);
console.log("-1148 => " + output);
output = sumDigits(0);
console.log("0 => " + output);
Multiply the result?
function sumDigits(input) {
return Math.abs(input)
.toString()
.split("")
.reduce((sum, num) => sum + Number(num), 0)
* (input < 0 ? -1 : 1);
}
One of the examples.
function sumDigits(num) {
newStr = Math.abs(num).toString();
var sum = 0;
for(var i=0; i < newStr.length; i++) {
sum = sum + parseInt(newStr[i]);
}
return num >= 0 ? sum : -sum ;
}
var output = sumDigits(1148);
console.log(output); // --> 14
var output = sumDigits(-1148);
console.log(output); // --> -14
var output = sumDigits(0);
console.log(output); // --> 0
When you pass a negative number into your sumDigits() function and convert it to a string, the first character becomes the sign (-). So, you should get the absolute value to get rid of the sign. However, if you're expecting a negative value, then you should define a flag that indicates whether the parameter was a negative integer before it got converted, or simply multiply it again by the initial sign. So, you should modify your function like this:
function sumDigits(num) {
const seq = Math.abs(num).toString();
let sum = 0;
for (let i = 0; i < seq.length; i++) {
sum += parseInt(seq[i]);
}
return sum * Math.sign(num);
}

How can I count the number and calculate it? (i using isNaN())

My code is below. I'm using isNaN() but the problem is it's still valid
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
}
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
How can I count the number and calculate it?
When I using debugger sum is NaN .. I cant understand well.
The issue is that sum = sum + Number(str[i]) is being executed even if isNaN(Number(str[i])) === true because it is outside of the if block. You need to wrap it inside of the else block so that it only executes if the previous condition is false.
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
} else {
sum = sum + Number(str[i]) // if it's a number
}
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
The other way of doing this is with a continue statement. Think of continue the same way you think about an early return in a function, except for a loop.
For example, you've written:
function numberSearch(str) {
// . . .
if (str === "")
return 0
// . . .
}
This is called an "early return" or "early exit." The same technique can be used in a loop:
for (let i = 0; i <= 10; i++) {
if (i % 3 === 0) // matches every multiple of 3 (3, 6, 9, etc.)
continue;
console.log(i)
}
Here is your code again, this time using continue.
function numberSearch(str) {
let sum = 0
let strCount = 0
if (str === "") {
return 0
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1 // if it's true, +1
continue
}
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum / strCount);
}
//debugger;
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 1
I recommend you go with the if-else version because for a loop as simple as this, the use of continue adds a little unnecessary metal-overhead.
That being said, if the logic within the loop grows (the part in the else statement), you may find it is easy to read if you do use the continue method. In the end, what really matters is what you personally feel is easier to read.
I would probably do it slightly different than in the original code, and find out how many numbers there are, and work from there
function numberSearch(str) {
if (!str) {
// early exit for null or ''
return 0;
}
// get all the chars, filter the non-numbers
const numbers = str.split('').filter( v => !isNaN(Number(v)));
// map all the numbers to numbers and sum them up
const sum = numbers.map( Number ).reduce( (agg, item) => agg + item, 0 );
// divide the sum by the length of the string - the amount of numbers found
// but always by at least 1 (so not to get a divide by 0 error when only all numbers are given)
return Math.round( sum / Math.max(1, str.length - numbers.length) );
}
let output = numberSearch('Hello6 ');
console.log(output); // --> 1
output = numberSearch('Hello6 9World 2,');
console.log(output); // --> 2
output = numberSearch('111111111');
console.log(output); // --> 9
output = numberSearch('');
console.log(output);
For the original code however, you should just add a continue in your if branch and your code will work (as long as not all characters are numbers, cause then you would divide by 0 and you didn't specify how to handle such a case)
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1; // if it's true, +1
continue;
}
sum = sum + Number(str[i]); // if it's a number
}
Just remember to verify to not divde by 0 if all are numbers :)
Your main issue is that you add a number anyway. In the line sum = sum + Number(str[i]) is read for each and every character. So even the last char will be NaN and it would be added to the sum, making it NaN.
I'm not quite sure what you're trying to do here, it seems like you are trying to get the sum and divide it by the number of non number characters.
You need to skip those in the sum. There are plenty of ways to do it, and some other problems with the code, but to keep the changes to your code to a minimum I say, just do this:
function numberSearch(str) {
let sum = 0;
let strCount = 0;
if (str === "") {
return 0;
};
for (let i = 0; i < str.length; i++) {
if (isNaN(Number(str[i]))) {
strCount = strCount + 1; // if it's true, +1
} else {
sum = sum + Number(str[i]); // if it's a number
}
}
return Math.round(sum / strCount);
}
Think of the following case
for(let i = 0 ; i<str.length ; i++){
//str[0] is 'H', so fall into the first if-case
if(isNaN(Number(str[i]))){
strCount = strCount + 1 // if it's true, +1
}
//the code keep running but 'H' shouldn't fall into the following case
sum = sum + Number(str[i]) // if it's a number
}
return Math.round(sum/strCount);
I suggest you add one more if-else for each case which clearly state out each of the case. This makes it easier to recall memory when you come across the code days or months later.
for(let i = 0 ; i<str.length ; i++){
if(isNaN(Number(str[i]))){
strCount = strCount + 1
}else if(typeof str[i] === 'number'){
sum = sum + Number(str[i])
}
}
return Math.round(sum/strCount);

I keep getting a bunch of numbers as my output in the console

I am working on this question:
Given a non-negative integer num, repeatedly add all its digits until the result has only one digit.
Example:
Input: 38
Output: 2
Explanation: The process is like: 3 + 8 = 11, 1 + 1 = 2.
Since 2 has only one digit, return it.
here is my code:
const addDigits = (num) => {
while(num > 9){
let strNum = num.toString()
let count = 0;
console.log(strNum)
for(let i = 0; i < strNum.length; i++){
count += Number(strNum[i])
//while number is greater than 9 we have to keep going
}
}
num = count
console.log(num)
};
addDigits(38)
I keep getting a bunch of numbers in my console instead of the desired output. Can someone tell me whats wrong with the code?
You need to set num = count at the end of each loop iteration, instead of outside the loop.
const addDigits = (num) => {
while(num > 9){
let strNum = num.toString()
let count = 0;
console.log(strNum)
for(let i = 0; i < strNum.length; i++){
count += Number(strNum[i])
//while number is greater than 9 we have to keep going
}
num = count; //moved to last statement of each iteration
}
console.log(num)
};
addDigits(38)

Summing a number's digits

My code below. Can someone see the mistake I made?
Write a function named sumDigits which takes a number as input and returns the sum of the absolute value of each of the number's decimal digits. For example:
sumDigits(10); // Returns 1
sumDigits(99); // Returns 18
sumDigits(-32); // Returns 5
Let's assume that all numbers in the input will be integer values.
function sumDigits(number) {
let numberstring = number.toString()
let numberarr = numberstring.split("")
let counter = 0
for(var i=0; i<numberarr.length; i++) {
if(typeof numberarr[i] === "number") {
console.log(numberarr[i])
let numbervalue = Number(numberarr[i])
console.log(numbervalue)
counter += numbervalue
} else if (typeof numberarr[i] !== "number"){
counter += 0
}
}
return counter
}
console.log(Math.abs(sumDigits(10))); // Returns 1
console.log(Math.abs(sumDigits(99))); // Returns 1
console.log(Math.abs(sumDigits(-32))); // Returns 1 // Returns 5
//Let's assume that all numbers in the input will be integer values.
function sumDigits(number) {
var counter = 0;
var remainder;
number=Math.abs(number);
while(number>0){
counter=counter+number%10;
number=Math.floor(number/10);
}
return counter;
}
I think you are looking for some code like this. i don't get why you convert your number to string.
number=Math.abs(number); this line first convert any negative number to positive.
sumDigits(number) takes an argument as now loop through the number until number < 0 then add the remainder to counter variable then return counter as final sum
Try this solution:
console.log(sumDigits(-103)); // Returns 4
function sumDigits(number) {
var numberstring = number.toString();
var counter=0;
for(var i=0; i<numberstring.length; i++){
if(parseInt(numberstring.charAt(i))){
counter += parseInt(numberstring.charAt(i));
}
}
return counter;
}
This
if(typeof numberarr[i] === "number")
statement is always false, because before you convert the number into a string. I think that your function return always zero.
The answer by giovybus & Raman are correct, if you were wondering why your snippet didn't work - it's because the reference of the numberer[I] will always be a string. numberarr is a string array, not a number array, you needed to convert it to a number before using. Adjustments to your code above as below
sumDigits(10); // Returns 1
sumDigits(99); // Returns 18
sumDigits(-32);
function sumDigits(number) {
let numberstring = number.toString().replace("-", "");
let numberarr = numberstring.split("")
let counter = 0
for(var i=0; i<numberarr.length; i++) {
const numbervalue = Number(numberarr[i])
if(typeof numbervalue === "number") {
counter += numbervalue
} else if (typeof numbervalue !== "number"){
counter += 0
}
}
console.log(counter)
return counter
}
However this is not a good solution and you should consider using solution by giovybus, Raman or anyone else with better approach instead.
Using filter and reduce to calculate the total.
function sumDigits(number) {
return ( [...number.toString()]
.filter( (char) => !isNaN(parseInt( char ) ) )
.reduce( function(a,b) { return a + parseInt(b) }, 0) );
}
const sum1 = sumDigits(103);
console.log( sum1 );
const sum2 = sumDigits(-105);
console.log( sum2 );
Using latest ES6 syntax...
function sumDigits(num) {
return [...num.toString()].map(Number).reduce((acc, val) => acc + val, 0);
};
console.log(sumDigits(55)); // 10
Explanation of tricky parts:
This will split the string into an array of digits:
[..."1234"] // => [ "1", "2", "3", "4" ]
This will transform it into Numbers
[ "1", "2" ].map(Number) // => [ 1, 2 ]

function sumDigits; How do I get this function to work with a negative number?

Question:
Write a function called sumDigits.
Given a number, sumDigits returns the sum of all its digits.
var output = sumDigits(1148);
console.log(output); // --> 14
If the number is negative, the first digit should count as negative.
var output = sumDigits(-316);
console.log(output); // --> 4
This is what I currently have coded and it works for positive values but I can't wrap my head around how to tackle the problem when given a negative value. When -316 is put into the function, NaN is returned and I understand that when I toString().split('') the number, this is what is returned: ['-', '3', '1', '6']. How do I deal with combining index 0 and 1?
function sumDigits(num) {
var total = 0;
var newString = num.toString().split('');
for (var i = 0; i < newString.length; i ++) {
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
sumDigits(1148);
Any hints on what methods I should be using? and is there a smarter way to even look at this?
This should do it:
function sumDigits(num) {
var total = 0;
var newString = num.toString().split('');
for (var i = 0; i < newString.length; i ++) {
if(newString[i]==='-') { //check to see if the first char is -
i++; //if it is, lets move to the negative number
var converted = parseInt(newString[i]); // parse negative number
total -= converted; // subtract value from total
continue; // move to the next item in the loop
}
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
console.log(sumDigits(-316));
You could always use String#replace with a function as a parameter:
function sumDigits (n) {
var total = 0
n.toFixed().replace(/-?\d/g, function (d) {
total += +d
})
return total
}
console.log(sumDigits(-1148)) //=> 14
One way to do this, is to do a split that will keep the minus and the first digit together, not split.
You can do that with a regular expression, and use match instead of split:
var newString = num.toString().match(/-?\d/g);
function sumDigits(num) {
var total = 0;
var newString = num.toString().match(/-?\d/g);
for (var i = 0; i < newString.length; i++) {
var converted = parseInt(newString[i]);
total += converted;
}
return total;
}
var result = sumDigits(-316);
console.log(result);
In a bit shorter version, you could use map and reduce, like this:
function sumDigits(num) {
return String(num).match(/-?\d/g).map(Number).reduce( (a, b) => a+b );
}
console.log(sumDigits(-316));
Is there a smarter way to even look at this?
You can avoid the conversion from number to string and back by using the modulo operator to extract the last digit. Repeat this step until you got all digits:
function sumDigits(num) {
let total = 0, digit = 0;
while (num != 0) {
total += digit = num % 10;
num = (num - digit) * 0.1;
}
return total < 0 ? digit + digit - total : total;
}
console.log(sumDigits(-316)); // 4
console.log(sumDigits(1148)); // 14
console.log(sumDigits(Number.MAX_SAFE_INTEGER)); // 76
function sumDigits(num) {
let string = num.toString();
let zero = 0;
let total = 0;
for (var i = 0; i < string.length; i++) {
if (Math.sign(num) === 1) {
total = zero += Number(string[i]);
} else {
for (var i = 2; i < string.length; i++) {
total = (zero += Number(string[i])) - Number(string[1]);
}
}
}
return total;
}

Categories

Resources