This question already has answers here:
How to force JS to do math instead of putting two strings together [duplicate]
(11 answers)
Closed 7 years ago.
I have to write 6 small JavaScript scripts for school and I've got them all working apart from this one.
function calculate() {
var numbers = [
document.getElementById("num_one").value ,
document.getElementById("num_two").value ,
document.getElementById("num_three").value
];
var sum = numbers[0] + numbers[1] + numbers[2];
document.getElementById("display_sum").innerHTML = sum;
}
The user is supposed to enter 3 numbers click a button and it should add them all togther or "find the sum".
My Problem is, it just joins the numbers togther instead of adding them. Does anyone know a way to fix this?
You are "summing" string variables so Javascript is concatenating them.
You need to convert them to numbers in order to have an arithmetic sum:
function calculate() {
var numbers = [
document.getElementById("num_one").value ,
document.getElementById("num_two").value ,
document.getElementById("num_three").value
];
var sum = Number(numbers[0]) + Number(numbers[1]) + Number(numbers[2]);
document.getElementById("display_sum").innerHTML = sum;
}
Parse string using parseFloat(), parseInt() or Number(), for converting it's to number. Otherwise + will just do string concatenation , since the values are string.
function calculate() {
var numbers = [
document.getElementById("num_one").value,
document.getElementById("num_two").value,
document.getElementById("num_three").value
];
var sum = parseFloat(numbers[0]) + parseFloat(numbers[1],) + parseFloat(numbers[2]);
document.getElementById("display_sum").innerHTML = sum;
}
function calculate() {
var numbers = [
document.getElementById("num_one").value,
document.getElementById("num_two").value,
document.getElementById("num_three").value
];
var sum = Number(numbers[0]) + Number(numbers[1]) + Number(numbers[2]);
document.getElementById("display_sum").innerHTML = sum;
}
function calculate() {
var numbers = [
document.getElementById("num_one").value,
document.getElementById("num_two").value,
document.getElementById("num_three").value
];
var sum = parseInt(numbers[0], 10) + parseInt(numbers[1], 10) + parseInt(numbers[2], 10);
document.getElementById("display_sum").innerHTML = sum;
}
The value property is string. In order to use it in arithmetic operations, you need to parse it to integers. The simpliest way to do this in JS is +x. You can use Array.prototype.map and Array.prototype.reduce to make it easier:
var ids = ['num_one', 'num_two', 'num_three'];
var sum = ids
.map(function(x) { return +document.getElementById(x).value; })
.reduce(function(a,b) { return a+b; }, 0);
With this way, you will be able to introduce new elements into calculations with minimal changes.
.value return String you need convert it to Number,
you can do it with parseInt or parseFloat(if you have float values), or with Number() or just add + before value
var numbers = [
+document.getElementById("num_one").value,
+document.getElementById("num_two").value,
+document.getElementById("num_three").value
];
or
var numbers = [
Number(document.getElementById("num_one").value),
Number(document.getElementById("num_two").value),
Number(document.getElementById("num_three").value)
];
or
var numbers = [
parseInt(document.getElementById("num_one").value, 10),
parseInt(document.getElementById("num_two").value, 10),
parseInt(document.getElementById("num_three").value, 10)
];
The shortest approach is to use Array.prototype.map
The map() method creates a new array with the results of calling a provided function on every element in this array.
in combination with Number
The Number JavaScript object is a wrapper object allowing you to work with numerical values. A Number object is created using the Number() constructor.
The primary uses for the Number object are:
If the argument cannot be converted into a number, it returns NaN.
In a non-constructor context (i.e., without the new operator), Number can be used to perform a type conversion.
and then Array.prototype.reduce
The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.
in combination with a callback like
function (a, b) {
return a + b;
}
Together in a single line with your code wrapped:
function calculate() {
var numbers = [
document.getElementById("num_one").value,
document.getElementById("num_two").value,
document.getElementById("num_three").value
],
sum = numbers.map(Number).reduce(function (a, b) { return a + b; });
document.getElementById("display_sum").innerHTML = sum;
}
A scalable solution in one line of es6:
var sum = numbers.reduce((a, b) => Number(a) + Number(b), 0);
Be sure to include an initialValue at the end there - it'll guarantee the callback is executed and a number is returned in cases where the array contains no values/one value.
More info on reduce
Depending on whether your input numbers are integers or decimals, you can use parseInt or parseFloat.
There are already plenty of reasonable answers, but here's a neat shorthand alternative:
var sum = +numbers[0] + +numbers[1] + +numbers[2];
I think you can use an array to store the inputs like
<script>
var numbers;
function push(){
numbers.push(getDocumentById("someid").val;
}
function calculate(){
var sum=0;
for(i=0; i<numbers.len; i++){
sum=sum + numbers[i];
}
alert(sum);
}
</script>
<div>
<button id="someid" value=20 onClick="addToArray();">click to push</button>
</div>
<div>
<button id="calc" onClick="calculate();">click to calculate</button>
</div>
The following will solve the problems:
function calculate() {
var numbers = [
+(document.getElementById("num_one").value) ,
+(document.getElementById("num_two").value) ,
+(document.getElementById("num_three").value)
];
var sum = numbers[0] + numbers[1] + numbers[2];
document.getElementById("display_sum").innerHTML = sum;
}
By default, javascript treats input values as strings. So you have to manually convert them to integers like this:
var numbers = [
document.getElementById("num_one").value ,
document.getElementById("num_two").value ,
document.getElementById("num_three").value
];
document.getElementById("display_sum").innerHTML =
numbers
.reduce(function(sum, element) { return sum + parseInt(element, 10);}, 0);
What is good about this code, is that if you need to calculate for more than three elements you only need to modify your numbers array.
Related
I just started learning about reduce method, and stuck in this problem...
N answer
123 6
987 24
An example would be 9 + 8 + 7 = 24 but the parameter is in number.
Here is what I have tried:
function solution (n){
let result = new Array (n)
let answer = result.reduce((a,b) => {
return a + b
})
}
Here is my code but I'm getting TypeError [Error]: Reduce of empty array with no initial value
Here's how you would use reduce to calculate the sum -
[...String(123)].map(Number).reduce((a,b) => a+b, 0)
This:
let result = new Array (n)
creates an empty array with a length of n.
In order to convert a number to an array of digits, you can use this little handy snippet:
const arr = n.toString().split('').map(Number)
We are getting n as a string, then splitting it into an array of characters, and then mapping each character to its corresponding digit.
After that you can use the reduce function:
let answer = arr.reduce((a,b) => {
return a + b
});
I have only been learning javascript for 2 weeks, so apologies if my question seems weird/doesn't make sense. I'm learning the basics of arrays, and to help me learn I like to practise and play around with the code but I can't seem to figure this one out.
I've created a simple function, and wanting to call upon the function to calculate the sum of variables in an array. Here is my code below:
//functions
function simpleCalc (a,b) {
var result = a + b;
return result;
}
//array
var myArray = [12,567];
//final calculation
var total = simpleCalc([0],[1]);
alert("The total is " + total);
Can anyone please shed any light as to how I input the numbers "12" and "567" into the function parameters? The result here as it stands outputs to "01"
Thanks
You have two options:
Your option but, it is very limited to only two values.
You need to pass reference to your array elements like so (myArray[0], myArray[1])
Create new function - let's call it sumValuesInArray(), pass an array and calculate all values inside an array using for loop.
See working example here:
//functions
function simpleCalc (a,b) {
var result = a + b;
return result;
}
//array
var myArray = [12,567];
//final calculation
var total = simpleCalc(myArray[0],myArray[1]);
//alert("The total is " + total);
// OR
function sumValuesInArray(array) {
var total = 0;
for(i = 0; i < array.length; i++) {
var element = array[i];
total += element;
}
return total;
}
console.log(sumValuesInArray(myArray));
You don't specify the array but only indexes :
var total = simpleCalc([0],[1]);
So, it passes two array objects : [0] and [1].
The concatenation of them here :
var result = a + b;
has as result the 01 String.
To pass the two first elements of myArray, try it :
var total = simpleCalc(myArray[0],myArray[1]);
You need to access the array values by index. You do this using the brackets WITH the name of the array. If you pass the brackets with numbers inside, you're creating new arrays.
It should be:
var total = simpleCalc(myArray[0],myArray[1]);
Write a single function that outputs the “largest” phone number in an input array (if multiple numbers are equally large, return the last one). Assume that the phone numbers are strings of 10 digits separated by dashes.
I wrote a function to answer the questions above. It comes out undefined. can someone help me find the error please. I feel that i am close to the answer.
var largestNumber = function(strings) {
var ints = strings.map(function(el) {
return el.replace(/-/g, '').split('').reduce(function(previousValue, currentValue, currentIndex, array) {
return previousValue + currentValue;
});
});
console.log(ints);
var largest = Math.max.apply(Math, ints);
return strings[ints.lastIndexOf(largest)];
};
console.log(largestNumber(['111-111-1111', '111-111-1112', '111-111-1113']));
ints.lastIndexOf(largest)
This part searches for the last occurence of largest in ints. However, largest will always be a number, but ints contains only strings. Therefore, the number isn’t found and undefined is returned. To fix this, convert largest back to a string:
ints.lastIndexOf(largest.toString())
Also, you don’t need to split the strings and concatenate them back together.
This code is working:
var largestNumber = function(strings) {
var ints = strings.map(function(el) {
return el.replace(/-/g, '');
});
console.log(ints);
var largest = Math.max.apply(Math, ints);
return strings[ints.lastIndexOf(largest.toString())];
};
console.log(largestNumber(['111-111-1111', '111-111-1112', '111-111-1113']));
Alternatively, you could map the strings to numbers:
var ints = strings.map(function(el) {
return Number(el.replace(/-/g, ''));
});
Since you are already using reduce() why not use one reduce() to return the highest
var largestNumber = function(strings) {
return strings.reduce(function(previousValue, currentValue) {
return +currentValue.replace(/-/g,'') >
+previousValue.replace(/-/g,'') ? currentValue : previousValue;
});
};
alert(largestNumber(['111-111-1111', '111-111-1112', '111-111-1113']));
var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = [];
console.log(strings);
strings.forEach(function(entry) {
var ints = entry.replace(/-/g, '');
console.log(ints);
});
var myResults = ints.map(function (el) {
return el.toString().split('').reduce(function (sum, b) {
return sum + +b;
}, 0);
});
console.log(myResults);
I have an array of strings that I want to take out the dashes then store the new arrays as ints. I am trying to reduce each array of ints to create a myResults that print out 53, 30, 33. I know there is something wrong with this code because the mapping and reduce doesn't want to work.
You need to push entry values in ints array after replace
var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = [];
strings.forEach(function(entry) {
ints.push(entry.replace(/-/g, ''));
});
var myResults = ints.map(function (el) {
return el.toString().split('').reduce(function (sum, b) {
return sum + +b;
}, 0);
});
alert(myResults);
You can combine your statements like this (in a working snipppet):
var strings = [ '234-496-7459', '760-644-0201', '555-222-3333' ];
var ints = strings.map(function(item) {
return item.replace(/-/g, '').split('').reduce(function(total, val) {
return total + +val;
}, 0);
});
document.write(JSON.stringify(ints));
Explanation:
You want to convert one array to another so use .map() not .forEach().
Then, right in the .map() callback, you can convert the string to total.
.replace(/-/g, '').split('') gets rid of the dashes and turns it into an array of letters.
.reduce() then runs on that array to sum up all the digits.
If you're looking for another way, you can use
Array#map, String#replace, String#split, Array#reduce with Arrow function syntax.
You can use RegEx /\d/g with String#match to get individual numbers as an array.
var ints = arr.map(el => el.match(/\d/g, '').reduce((sum, a) => sum + +a, 0));
\d matches a single digit. g is global flag, to get all the possible matches.
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(el => el.match(/\d/g, '').reduce((sum, a) => sum + +a, 0));
console.log(ints);
document.write(ints);
String#replace and String#split can also be used.
var ints = arr.map(el => el.replace(/-/g, '').split('').reduce((sum, a) => sum + +a, 0));
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(el => el.replace(/-/g, '').split('').reduce((sum, a) => sum + +a, 0));
console.log(ints);
document.write(ints);
Equivalent code in ES5
var ints = arr.map(function (el) {
return el.replace(/-/g, '').split('').reduce(function (sum, a) {
return sum + +a;
}, 0);
});
var arr = ['234-496-7459', '760-644-0201', '555-222-3333'];
var ints = arr.map(function(el) {
return el.replace(/-/g, '').split('').reduce(function(sum, a) {
return sum + +a;
}, 0);
});
console.log(ints);
Approach this in top-down fashion, step-by-step. For each step, we will write a little spec so we are perfectly clear on what we want to do. If we write the spec well, then the JS will follow easily.
We want to write a function sum_digits_of_array, for which the spec is:
sum_digits_of_array
Given an input array, return a new array, where each element is the sum of the digits of the corresponding element from the original array.
That is exactly the definition of map, so we can write:
function sum_digits_of_array(a) { return a.map(sum_digits); }
Now we just need to write sum_digits. We will also write a spec for that:
sum_digits
Given an input string, return the sum of the digits of the string.
That's easy enough:
function sum_digits(s) { return sum(digits(s)); }
Now for digits. Again we will write a little spec for ourselves:
digits
Given a input string, return array of individual digits, as numbers.
Instead of thinking of this as removing dashes and then splitting, we will use RegExp#match to just extract the digits:
function digits(s) { return s.match(/\d/g) . map(Number); }
Then
sum
Given an array of numbers, return the sum of all the numbers.
This is the definition of reduce, so
function sum(a) { return a.reduce(add); }
Then
add
Given two numbers, return the result of adding them
function add(a, b) { return a + b; }
That's it. So the entire solution, which is slightly more compact if we use ES6 arrow functions:
function sum_digits_of_array(a) {
const sum_digits = s => sum(digits(s));
const digits = s => s.match(/\d/g) . map(Number);
const sum = a => a . reduce(add);
const add = (a, b) => a + b;
return a . map(sum_digits);
}
Why code in this fashion? There are a number of good reasons.
You can read the code and tell what it's doing.
Related to that, it's easy to figure out where to modify the code if the problem changes.
We can easily test each little function to make sure it's working right.
The little functions we wrote might come in handy when solving a related problem, so we reduce the amount of work we have to do in the future.
I'm confused on why one is returning me the sum while the other one is just returning the list.
This correctly returns the output 10
function sum(){
var arrays = [1,2,3,4].reduce(function (total, num) {
return total + num;
})
console.log(arrays);
}
This however, returns [1, 2, 3, 4] and not 10.
function sum(){
var arrays = [1,2,3,4];
arrays.reduce(function (total, num) {
return total + num;
})
console.log(arrays);
}
At first I thought it's where I was declaring the var arrays so I tried moving it out of the function and also tried not declaring it var. However for this one I'm still not getting 10.
What's the difference between the two that I'm not getting the correct output?
Thanks.
You are missing the assignment, which is returned by the reduce:
function sum() {
var arrays = [1, 2, 3, 4];
arrays = arrays.reduce(function(total, num) {
//-----^
return total + num;
})
console.log(arrays);
}
In the second function you are ignoring the return value from the reduce method. It will correctly calculate the sum, but you don't use it.
Assign the result to the variable as in the first function:
array = arrays.reduce(function (total, num) {
return total + num;
});
However, having the result in the same variable as where the array was makes the code somewhat confusing. You should avoid having a variable change meaning in the middle of the code, so you can use a different variable for the result:
function sum(){
var arrays = [1,2,3,4];
var result = arrays.reduce(function (total, num) {
return total + num;
});
console.log(result);
}
Side note: The term functional programming is used for languages that are based on functional expressions instead of variable state. Just using a function doesn't mean that you are using functional programming.
In first,
when the function return the value i.e. 10 it is getting stored in var arrays and you are printing it.
whereas,
In second,
You declared the var arrays and give it the value [1,2,3,4] then funtion is called, the returned value is not getting stored anywhere and at last you are simply printing the var arrays which is [1,2,3,4]