I am writing a function called "computeAverageOfNumbers".
Given an array of numbers, "computeAverageOfNumbers" returns their average.
Notes:
If given an empty array, it should return 0.
Here's my code:
function computeAverageOfNumbers(nums) {
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
var input = [];
var output = computeAverageOfNumbers(input);
console.log(output); // --> returns NaN instead of 0
As you can see my code returns NaN when you submit an empty array but works if you put regular array items like var input = [1,2,3,4,5];
If given an empty array, it should return 0.
Am I missing something?
Just do below
if( nums.length == 0 ) return 0;
in code
function computeAverageOfNumbers(nums) {
if (nums.length == 0) return 0;
var total = 0;
for (var i = 0; i < nums.length; i++){
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
Just check if nums.length
function computeAverageOfNumbers(nums) {
if (nums.length === 0) {
return 0
} else {
var total = 0;
for (var i = 0; i < nums.length; i++) {
total += nums[i];
}
var avg = total / nums.length;
return avg;
}
}
var input = [];
var output = computeAverageOfNumbers(input);
console.log(output);
input = [2,5,9,13];
output = computeAverageOfNumbers(input);
console.log(output);
When your array is empty, nums.length = 0 and a if you divide a number by 0, it gives you NaN.
Just change
var avg = total / nums.length;
to
var avg = (nums.length)?total/nums.length:0
to solve your trouble
When you pass an empty array then this line:
var avg = total / nums.length;
Is a division by zero, so avg will be NaN. I would short circuit the function at the start with:
if (nums.length === 0)
return 0;
Bear in mind ideally you also want to do some type checking to confirm you've got an array, etc. but the above should give you the basics.
Related
As can be seen from the title I'm having some issues getting my code to work. If I choose min, max, or sum, they post the correct output but then the other two buttons return undefined for min/max if Sum was done first and return as 0 sum if min or max was chosen first. Any and all help is appreciated, apologies for my ignorance.
Here is what I've been working with:
function GetSum(){
for (var index = 0; index < arr.length; index++) {
number += arr[index];
}
return number;
}
function ShowSum(){
let sum = GetSum();
if(arr = !isNaN && arr.length> 0){
return sum;}
ShowData("sum",sum);} //ShowData posts the sum to HTML page
function GetMaximum(){
let i;
var largest =arr[0];
for(i = 1; i < arr.length; i++){
if(arr[i]>largest) { largest = arr[i];
}return largest;
}console.log(largest); }
// this all works fine, then when other buttons are chosen it's no go
function ShowMax(){
let maxNum = GetMaximum(arr);
if(arr = !isNaN && arr.length> 0){
return maxNum
} ShowData("max",maxNum);}
Why is ShowMax displaying the correct result, but unidentified when I've already used ShowSum?
It's the same testing in the console too. Same with ShowSum returning 0 once I've had a correct go with ShowMax. Thanks everybody
you have multiple problem, isNaN() is a function to check if string is number or not, then use parseInt() to convert string to number.
the GetMaximum() will not alyways return largest number because it set return in for loop and there will be remaining value.
function GetSum() {
let number = 0;
for (var index = 0; index < arr.length; index++) {
if (!isNaN(arr[index]))
number += parseInt(arr[index]);
}
return number;
}
function ShowSum() {
let sum = 0;
if (arr.length > 0) {
sum = GetSum();
}
ShowData("sum", sum);
return sum;
}
//ShowData posts the sum to HTML page
function GetMaximum() {
let i, largest = 0;
for (i = 1; i < arr.length; i++) {
let num = isNaN(arr[i]) ? 0 : parseInt(arr[i]);
if (num > largest) {
largest = parseInt(arr[i]);
}
}
//console.log(largest);
return largest;
}
function ShowMax() {
let maxNum = 0;
if (arr.length > 0) {
maxNum = GetMaximum(arr);
}
ShowData("max", maxNum);
return maxNum
}
function ShowData(...args) {
return console.log(args.join(' '))
}
var arr = [2.3, 6, 8, 1];
ShowMax()
ShowSum()
I have written a function and called another function inside but my tests show that it is not time optimized. How can I make the following code faster?
function maxSum(arr, range) {
function sumAll(array1, myrange) {
var total = 0;
if (Array.isArray(myrange)) {
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
return total;
} else return array1[myrange];
}
var mylist = [];
var l = range.length;
for (var n = 0; n < l; n++) {
mylist.push(sumAll(arr, range[n]));
}
return Math.max.apply(null, mylist);
}
Algorithmic optimization: create new array with cumulative sums from index 0 to every index
cumsum[0] = 0;
for (var i = 1; i <= arr.Length; i++) {
cumsum[i] = cumsum[i-1] + arr[i-1]
Now you don't need to calculate sums for every range - just get difference
sum for range (i..j) = cumsum[j+1] - cumsum[i];
in your terms:
function sumAll(array1, myrange) {
return cumsum[myrange[1]+1] - cumsum[myrange[0]];
}
example:
arr = [1,2,3,4]
cumsum = [0,1,3,6,10]
sum for range 1..2 = 6 - 1 = 5
P.S. If your array might be updated, consider Fenwick tree data structure
1) You can define the function sumAll outside of the function maxSum because every time you call maxSum the javascript engine is recreating a fresh new function sumAll.
2) You can define myrange[1] as a variable in the initialiser part to avoid javascript to look for myrange[1] at each iteration.
for (var i = myrange[0]; i <= myrange[1]; i++) {
total += array1[i];
}
become this:
for (var i = myrange[0], len = myrange[1]; i <= len; i++) {
total += array1[i];
}
Full working code based on #MBo's excellent optimization. This passes all the tests at https://www.codewars.com/kata/the-maximum-sum-value-of-ranges-challenge-version/train/javascript, which I gather is where this problem comes from.
function maxSum(arr, ranges) {
var max = null;
var sums = [];
var sofar = 0;
for (var i = 0; i <= arr.length; i++) {
sums[i] = sofar;
sofar += arr[i];
}
for (var i = 0; i < ranges.length; i++) {
var sum = sums[ranges[i][1]+1] - sums[ranges[i][0]];
if (max === null || sum > max) {
max = sum;
}
}
return max;
}
when I run this program I end up with NaN at the end; I'd appreciate some form of explanation, as I'm stumped! I have an odd feeling it has to do something with scope...
https://jsfiddle.net/Smuggles/evj46a23/
var array = []
var range = function(start, end) {
for (var count = start; count <= end; count++) {
array.push(start);
start += 1;
}
console.log(array);
}
var sum = function() {
var result = 0
var arrayLength = array.length
for (var count = 0; count <= arrayLength; count++) {
result += array[count]
console.log(result);
}
}
console.log(sum(range(1, 10)));
2 things:
You need to change the for loop in the sum function to be < arrayLength and not <= arrayLength. You are dealing with array lengths which start with a 0 index.
You need to return the result from the sum function
var array = [];
var range = function(start, end) {
for (var count = start; count <= end; count++) {
array.push(start);
start += 1;
}
};
var sum = function() {
var result = 0;
var arrayLength = array.length;
for (var count = 0; count < arrayLength; count++) {
result += array[count];
}
return result;
};
console.log(sum(range(1, 10)));
Given an array of [4,5,6], the indexes would be as follows:
0: 4
1: 5
2: 6
Therefore, when you use the length property of the array (3), you are referencing an index that does not exist, which returns undefined. It tries to do the math on the undefined, which causes a NaN. This is why you have to use < arrayLength.
The functional approach:
It would help to make those functions a bit more "pure". Instead of maintaining state outside of the functions (with var array = []), just return the values from the functions: See the following for example:
function range(start, end) {
var arr = [];
for (var i = start; i <= end; i++) {
arr.push(i);
}
return arr;
}
function sumArray(array) {
return array.reduce(function(a, b) {
return a + b;
});
}
console.log(sumArray(range(1, 10)));
Each function takes arguments, and simply returns the result. This way, you approach this a little more "functional".
Description in Comments of Code
var array = [];
var range = function(start, end) {
//simplified the loop to remove unnecessary variables
for (; start <= end; start++) {
array.push(start);
}
return array;
}
var sum = function() {
var result = 0;
// move length to scope of the loop
// change to < rather than <= due to zero index nature of arrays
for (var count = 0, length = array.length; count < length; count++) {
result += array[count];
}
// return the result from the function
return result;
}
// gets an array from 1-10
var arr = range(1, 10);
// print the array to the console
console.log(arr);
// print the sum to the console
console.log(sum(arr));
as the title says i'm trying to sum up using a for loop to iterate over an array.
can you give me some pointers as to where i'm going wrong here. i am returning the value NaN.
var total = 0;
function sum(input) {
for (idx=0; idx<=input; idx++) {
total += input[idx];
}
return total;
}
You actually don't need a loop to do this in modern browsers, you can use the Array.reduce function:
var sum = input.reduce(function(a,b){
return a+b;
}, 0);
You need ot declare total into function and also you need to declare idx. Another thing that instead of writing idx <= input.length you have to write idx <= input.length - 1. Since last index will be undefined.
Try
function sum(input) {
total = 0;
for (var idx = 0; idx <= input.length - 1; idx++) {
total += input[idx];
}
return total;
}
variable total is not declared!
function sum(input) {
var total = 0;
for (idx=0; idx <= input.length; idx++) {
total += input[idx];
}
return total;
}
You are using input both as an integer, and as an array of values. Probably you mean for( var idx = 0; idx < input.length; ++idx )....
Problem which result in NaN is because of your array traversing array till end, rather than from indices 0 to input.length-1
Try this:
http://jsfiddle.net/t9tfofxv/
var total = 0;
function sum(input) {
for (var idx=0; idx< input.length; idx++) {
total += input[idx];
}
return total;
}
var s=sum([1,2,3,4]);
alert(s);
Declare the variable total inside the function, and also use input.length-1 to define the loop's range:
function sum(input) {
var total = 0;
for (idx=0; idx <= input.length-1; idx++) {
total += input[idx];
}
return total;
}
I've got an array that is constantly updating with analogue readings from an Arduino pin.
I'd like to create a function that takes the latest 100 values in the array, and returns an average of them (the array has a max length of 100,000 at which it starts 'shifting' and 'pushing' to make space for new values).
I created this function, but it returns 'NaN' every time:
function returnAverage(){
var averageArray = [];
var sum = 0;
var sampleEnd = values.length
for (var x = sampleEnd - 100; x < sampleEnd; x++) {
averageArray[x] = values[x]
}
for(var i = 0; i < averageArray.length; i++){
sum += parseInt(averageArray[i]);
}
var avg = sum/averageArray.length;
console.log(avg)
}
Any ideas?
If values is a array of numbers, last maximum 100 items average:
function returnAverage(values) {
var arr = values.slice(-100);
return arr.reduce(function(a, b){ return a + b; }, 0) / (arr.length || 1);
}
Issue number one is that the final value of sum and averageArray.lnegth is 0.
It seems this would happen because the "value" array is empty.
See example below:
var values = [0,1,2,3,4,5,6];
var averageArray = [];
var sum = 0;
var sampleEnd = values.length
for (var x = sampleEnd - 7; x < sampleEnd; x++) {
averageArray[x] = values[x]
}
for(var i = 0; i < averageArray.length; i++){
sum += parseInt(averageArray[i]);
}
var avg = sum/averageArray.length;
console.log(avg)
Edit: NaN is a result of division by zero. So you might want to check for that before calculating:
if(sum == 0 || averageArray.length == 0)
{
return 0;
}