Average of array by using a callback function in Javascript - javascript

I'm having a problem to sum and find the average of an array. I keep getting average is 0.
I cant really see what the problem could be :
var a = [10,20,30,40]
var sum = 0
var avg = 0
function sumUP(a) {
for (var i=0; i<a.length; i++){
sum += a[i];
avg = (sum/a.length);
}
}
function display(avg, callback) {
document.write("Average of array is " + avg)
callback(average);
}
display(avg, sumUP);
thanks a lot in advance!

Instead of assigning to global variables, you should have sumUP return the calculated average so it can be used in your document.write. That's one of the purposes of functions - to encapsulate functionality and return values that can be used by other functions without unnecessary side-effects. You also need to calculate the average before you display it. (you were displaying it before you were calculating it, which of course leaves it displaying 0)
You should also take care not to use single-letter variable names, which are very hard to make sense of (not only for others reading your code, but also for you, when you come back to it later).
const array = [10, 20, 30, 40];
function sumUP(arr) {
let sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
const avg = (sum / arr.length);
return avg;
}
function display(arr, callback) {
const avg = callback(arr);
document.write("Average of array is " + avg)
}
display(array, sumUP);

You should write code like this.
function sumUP(a) {
for (var i=0; i<a.length; i++){
sum += a[i];
}
avg = (sum/a.length);
}

take a look at : .reduce()
const arr = [10, 20, 30, 40]
const sum = arr.reduce((a,b) => a + b , 0)
const avg = sum / arr.length
function display(avg) {
document.write("Average of array is " + avg)
}
display(avg);

You do not need to pass avg to the callback and display function at all:
var a = [10,20,30,40];
var sum = 0;
var avg = 0;
function sumUP() {
for (var i=0; i<a.length; i++){
sum += a[i];
res = (sum/a.length);
}
}
function display(callback) {
callback();
document.write("Average of array is: " + res);
}
display(sumUP);

Here is the fix for your code.
var a = [10,20,30,40]
var sum = 0
var avg = 0
function sumUP(a) {
for (var i=0; i<a.length; i++){
sum += a[i];
}
avg = (sum/a.length);
}
function display(callback) {
callback(a);
document.write("Average of array is " + avg);
}
display(sumUP);
The first problem in your code was you are calling the callback function after the document write. It should be called first before the writing the result because these method have your logic.
And the avg that you are calling is not the global variable that you declare but the variable that is being used by the function. I remove it in your parameter because it was already declared as global and no need to pass in the display function.
I also exlude avg = (sum/a.length); in the for loop because it can be computed once, and that is when the for loop is done or when you get the total sum of your numbers.

Related

Finding the sum of a "counter" variable loop that ran ten times then was pushed into the "numbers" array. Each way I tried resulted with a list

I'm asking for help to find the sum of an array with elements that were pushed from a counter variable that had previously looped 10 times. I'm new to Javascript and was practicing for an assessment, and I've tried several different ways to do it and have only resulted with just a list of the elements within the numbers array.
var counter = 10;
var numbers = [];
for (i = 1; i <= 10; i ++) {
counter = [i + 73];
numbers.push(counter);
}
console.log(numbers);
function sum(arr) {
var s = 0;
for(var i = 0; i < arr.length; i++) {
s = s += arr[i];
}
return s;
}
console.log(sum([numbers]));
function getArraySum(a) {
var total = 0;
for (var i in a) {
total += a[i];
}
return total;
}
var numbers = getArraySum([numbers]);
console.log(numbers);
you should push only the value of counter without the brackets and then make a reduce to have the sum of each number in the array
var counter = 10;
var numbers = [];
for (i = 1; i <= 10; i++) {
counter = i + 73;
numbers.push(counter);
}
console.log(numbers.reduce((a,b) => a+b));
You had a couple of typos in the code:
Typos
You were wrapping the sum in square brackets:
counter = [i + 73];
You should just remove the brackets like:
counter = i + 73;
2. You were wrapping a value that is already an array in square brackets while passing it as an argument to a function:
sum( [numbers] )
// ...
getArraySum( [numbers] );
You should remove the brackets, like this:
sum( numbers );
// ...
getArraySum( numbers );
Fix
I updated the code that you shared to fix the above-mentioned things:
var numbers = [];
// Loop 10 times and push each number to the numbers array
for (var i = 1; i <= 10; i ++) {
var sumNumbers = i + 73;
numbers.push(sumNumbers);
}
console.log(numbers);
function sum(arr) {
var total = 0;
for(var i = 0; i < arr.length; i++) {
total += arr[i];
}
return total;
}
// Call the function by passing it the variable numbers, holding an array
var result1 = sum(numbers);
console.log( result1 );
function getArraySum(a) {
var total = 0;
for (var i in a) {
total += a[i];
}
return total;
}
var result2 = getArraySum(numbers);
console.log(result2);

How do I write loops inside functions?

The question is to write a for loop inside a function that will take in array and return the total of all the numbers added together. Not sure what I'm doing wrong here.
let total = 0
function totalGoals(numbers) {
for (let i = 0; i<numbers.length; i++) {
let num = numbers[i]
total = total + num
}
return total
}
totalGoals([0, 1, 2])
First, lets confirm that you HAVE to learn the basics of Javascript and basic looping (using for loop for example), but also on your journey, you have to learn what tools in the language might make your life easier and your code mode readable.
When it comes to accumulative operation (like adding and so..) you should learn about "reduce" method, which you can write your desired function like:
function totalGoals(numbers){
return numbers.reduce((acc, val) => acc + val, 0)
}
You define total variable globally (outside of function), so here are 2 options: it's better to define variable for sum inside the function:
function totalGoals(numbers) {
let total = 0
for (let i = 0; i<numbers.length; i++) {
let num = numbers[i]
total = total + num
}
return total
}
totalGoals([0, 1, 2])
or if it is necessary to be global - set it to 0 in the start of function, so if won't be affected if function is called more than once:
let total = 0
function totalGoals(numbers) {
total = 0
for (let i = 0; i<numbers.length; i++) {
let num = numbers[i]
total = total + num
}
return total
}
totalGoals([0, 1, 2])
You have some sytanxys problems. Try this code:
function totalGoals(numbers) {
let total= 0, num = 0;
for (let i = 0; i< numbers.length; i++) {
num = numbers[i];
total = total + num;
}
alert(total);
return total;
}
totalGoals([0, 1, 2]);
You need to learn about Scope of variable:
https://www.w3schools.com/js/js_scope.asp
And you need be more carefully with your sintaxys:
Dont forget add ; at final of a code line.
And also you are start the variable num more than one time with the word let inside your loop.

JavaScript neglecting the else statement

I created a function which takes in two values..
Both are numbers represented by n & p. What the function does is that it gets the number n and splits it up then squares it to the value of p and sums them in an increasing order like this: n^p + n^(p+1) + n^(p+2) + ...
Here is the function
function digPow(n, p) {
// ...
let num = n.toString();
let pow = p;
let arrn = [];
let arrp = [];
for (let i = 0; i < num.length; i++) {
arrn.push(JSON.parse(num[i]));
}
let index = arrn.join('');
let sindex = index.split('');
for (let j = 0; j < sindex.length; j++) {
let power = p + j;
let indexs = sindex[j];
let Mathpow = Math.pow(indexs, power);
arrp.push(Mathpow);
}
let total = 0;
for (let m in arrp) {
total += arrp[m]
}
let secondVal = total / n;
let totals = total / secondVal;
let mx = [-1]
if (totals.length == n.length) {
return secondVal
} else {
return -1
}
}
Now i created variables and arrays to store up the values and then the if part is my problem.. The if/else statement is meant to let the program check if a particular variable totals is equal to n which is the input.. if true it should return a variable secondVal and if not it should return -1..
So far its only returning secondVal and i'snt returning -1 in cases where it should like:
digPow(92, 1) instead it returns 0.14130434782608695
What do i do?
totals and n are both numbers. They don't have a .length property, so both totals.length and n.length evaluate to undefined. Thus, they are equal to each other.
There are plenty of other weird things going on in your code, too. I'd recommend finding a good JavaScript tutorial and working through it to get a better feel for how the language (and programming in general) works.
Let's start by stripping out the redundant variables and circular-logic code from your function:
function digPow(n, p) {
let num = n.toString();
// let pow = p; // this is never used again
// let arrn = []; // not needed, see below
// let arrp = []; // was only used to contain values that are later summed; can instead just sum them in the first place
// this does the same thing as num.split(''), and isn't needed anyway:
//for (let i = 0; i < num.length; i++) {
// arrn.push(JSON.parse(num[i]));
//}
// this is the same as the original 'num' variable
// let index = arrn.join('');
// This could have been num.split(), but isn't needed anyway
// let sindex = index.split('');
let total = 0; // moved this line here from after the loop below:
for (let j = 0; j < num.length; j++) { // use num.length instead of the redundant sindex
let power = p + j;
// The only reason for the sindex array was to get individual characters from the string, which we can do with .charAt().
//let indexs = sindex[j];
let indexs = num.charAt(j);
let Mathpow = Math.pow(indexs, power);
//arrp.push(Mathpow); // No need to collect these in an array
total += Mathpow; // do this instead
}
// No need for this loop, since we can sum the total during the previous loop
// let total = 0;
//for (let m in arrp) {
// total += arrp[m]
//}
let secondVal = total / n;
// let totals = total / secondVal;
// The above is the same thing as total / total / n, which is:
let totals = 1/n;
// This is never used
//let mx = [-1]
// This was totals.length and n.length, which for numbers would always be undefined, so would always return true
if (totals == n) {
return secondVal
} else {
return -1
}
}
So the above reduces to this functionally identical code:
function digPow(n, p) {
let num = n.toString();
let total = 0;
for (let j = 0; j < num.length; j++) {
let power = p + j;
let indexs = num.charAt(j);
let Mathpow = Math.pow(indexs, power);
total += Mathpow;
}
let secondVal = total / n;
let totals = 1 / n;
if (totals == n) {
return secondVal
} else {
return -1
}
}
Now let's talk about the logic. The actual output will always be -1, unless the input is 1, due to what's clearly a logic error in the totals variable: the only case where 1/n == n is true is when n==1.
Setting that aside, and looking only at the secondVal variable, some examples of what it's calculating for a given input would be
digPow(123,1) --> (1^1 + 2^2 + 3^3) / 123 --> 14/123
digPow(321,2) --> (3^2 + 2^3 + 1^4) / 321 --> 21/321
digPow(92, 1) --> (9^1 + 2^2) / 92 --> 13/92
I'm pretty sure from your description that that's not what you intended. I'm not at all sure from your description what you did intend, so can't be much help in correcting the function beyond what I've done here.
What I'd suggest is to sit down and think through your algorithm first; make sure you know what you're trying to build before you start building it. There were some syntax problems with your code, but the real issues are with the logic itself. Your original function shows clear signs of "just keep throwing more lines of code at it until something happens" rather than any planned thinking -- that's how you wind up with stuff like "split a string into an array, then join it back into a string, then split that string into another array". Write pseudocode first: break the problem down into steps, think through those steps for some example inputs and make sure it'll produce the output you're looking for. Only then should you bust out the IDE and start writing javascript.

Return a piece of an array after finding the highest integer in java script?

So after working on finding the highest sum of any given amount of credit card numbers I realized I dug myself into a bit of a hole. (currently using 3 cards "123-123, 234-234 and 345-345" as test numbers.) After writing this out:
var howM = prompt("How many cards?")
var arr = [];
for(var i = 0; i < howM; i++)
arr.push(prompt("Enter a card:"));
console.log(arr)
var sumpre = [];
for(var i = 0; i < howM; i++) {
var sum = 0;
var eXt = arr[i];
eXt = eXt.replace (/-/g, "");
for (var j = 0; j < eXt.length; j++) {
sum += parseInt(eXt.substr(j, 1));
}
sumpre.push(sum);
}
console.log(sumpre);
var highest = sumpre[0];
for (var i=1; i<=sumpre.length; i++){
if (sumpre[i]>highest){
highest=sumpre[i];
}
}
console.log(highest)
Which works to find the highest sum, however; I need it to return the card number with the highest sum in its original form at the end and am not sure what method would be best to get back to that or if I should reformat it from the start.
As I mentioned in a comment, or as shown in Gerardo's answer, one way to do it with minimal changes to your current code is to use highest to keep the index of the array item with the highest value, instead of keeping the actual value itself - then you could retrieve the original card value via that index.
But for fun, here's another way to do it:
function sumDigitsInString(s) {
return Array.prototype.reduce.call(s, function(p, c) { return p + (+c || 0); }, 0);
}
function itemWithLargestSum(a) {
return a.reduce(function(p, c) {
var sum = sumDigitsInString(c);
return p[0] > sum ? p : [sum, c];
}, [0])[1];
}
// given an array of strings:
var input = ["123-123", "234-234", "345-345", "111-111"];
var largest = itemWithLargestSum(input);
console.log(largest);
Further reading:
.call() method
Array .reduce()
Unary plus operator
|| operator
?: (ternary) operator
You could also do something like this, just with Array methods.
var inputCards = ["989-000", "123-999", "456-456"];
var sum = 0,
sumNumbers = {},
maxVal = 0;
inputCards.map(function(num) {
var replaceText = new RegExp(/-/g);
var number = num.replace(replaceText, "").split("");
var prevVal = 0;
sumNumbers[num] = number.reduce((prevVal, currentVal) =>
parseInt(prevVal, 10) + parseInt(currentVal, 10));
});
console.log(Object.keys(sumNumbers).reduce((maxVal, currentVal) =>
sumNumbers[maxVal] > sumNumbers[currentVal] ? maxVal : currentVal));

Array summation based on length provided by user

I am trying to sum an array where array length will be provided by user. I have done it but execution time is high then required. What is an efficient way to do it. my code
function summation(){
var p = prompt("Number Only","");
var arr = [] ;
var sum = 0 ;
for (var i = 0; i < p; i++) {
arr.push(parseInt(prompt("Number Only","")));
};
for (var i = 0; i <arr.length; i++) {
sum += arr[i];
};
document.write(sum);
}
(function(){
summation();
})();
Why to use an array when you don't need an array?
function summation(){
var p = prompt("Number Only","");
var sum=0;
for(var i=0;i<p;i++){
sum+=parseInt(prompt("Number Only", ""));
}
document.write(sum);
}
This solution features an infinite loop with break, a prompt with control, a continuing input and a type checking for numbers.
The first imput for the array size is not more necessary, because of the possibillity of immediately ending with cancel or empty input.
function summation() {
var arr = [],
sum = 0,
v;
while (true) {
v = prompt("Number Only (Press [Cancel] for end input)", "");
if (!v) {
break;
}
v = parseInt(v, 10);
if (isFinite(v)) {
arr.push(v);
sum += v;
}
}
document.write('Array: ' + arr + '<br>');
document.write('Sum: ' + sum + '<br>');
}
summation();

Categories