I need to calculate the average value of my datas, my datas are in an
array the problem is when i parseInt them into an integer i only get
one value back and when try as an example following thing:
console.log(array[0]/24)
i dont get nothing
this is my array:
info my array is coming from php to js (php connected to api)
var signal_GW1 = dataFromAjax.data.data1.map(function(innerData){
return innerData.map(function(row){
return row[1];
});
});
console.log(signal_GW1);
//OUTPUT on BROWSER CONSOLE
[Array(136)]
0: Array(136)
[0 … 99]
0: "-59"
1: "-59"
2: "-59"
3: "-59"
4: "-53"
5: "-63"
To get the average of your array you could do the following.
As the response from the server is returning strings you need to use parseInt to convert to a number.
const array = ['-59', '-57', '-59', '-57'];
const average = array.reduce((accumulator, currentValue) => parseInt(accumulator) + parseInt(currentValue)) / array.length;
console.log(average);
const myArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let sum = 0
for (const value of myArray) { sum += value; }
const average = sum / myArray.length
console.log(`Average: ${average}`)
Basically: calculate the sum using Array.prototype.reduce, and divide the sum by the number of Array values (i.e. its length). About Array.prototype.reduce
const x = Array.apply(null, new Array(5))
.map(() => String(-Math.floor(100 * Math.random() + 1)));
// (+v) converts the string value to a Number
const meanX = x.reduce((a, v) => a + (+v), 0) / x.length;
console.log(`${JSON.stringify(x)} => Mean: ${meanX}`);
// or as a one liner
console.log(`Mean from one liner: ${
x.reduce( (a, v) => a + ((1/x.length) * +(v)), 0 ).toFixed(2)}`
);
Related
Please bear with me this is difficult to explain. I will first explain how to do it successfully with only one set of data.
First, say I have an array like so yValuesMinusMean = [-5, -4, -1, 10]
I have another array like so xValuesMinusMean = [ 2.75,3.75,6.75,5.75 ]
Both of the above arrays can have numerous values. However, the length of both arrays is the same. So if the first one has 4, then the second one will definitely have 4.
I want to calculate the sum and product of the arrays. This is what I mean:
var sumOfXTimesYValues = this.calculateProductAndSum(yValuesMinusMean, xValuesMinusMean);
calculateProductAndSum(yValuesMinusMean = [], xValuesMinusMean = []) {
let total = 0;
for(let i = 0; i < yValuesMinusMean.length; i++) {
let product = (yValuesMinusMean[i] * xValuesMinusMean[i]);
total += product;
};
return total;
},
The result of this: console.log('sumOfXTimesYValues', sumOfXTimesYValues); is
17
LOGIC : (-5 * 2.75) + (-4 * 3.75) + (-1 * 6.75) + (10 * 5.25) = 17
So far, everything works. However, I want to make it so that instead of xValuesMinusMean being a single array with multiple numerical values, it will be a single array containing multiple arrays, with each array having the same number of elements as in yValuesMinusMean. Like so:
xValuesMinusMean = [ [ 2.75,3.75,6.75,5.75 ], [-2,-1,2,1]. .... ]
END GOAL: sumOfXTimesYValues = [17, 22, ...]
Logic for the second array item: (-5 * -2) + (-4 * -1) + (-1 * 2) + (10 * 1) = 22
Essentially, you're multiplying each value in each array in xValuesMinusMean with a value in yValuesMinusMean in the same order. So, -5 is the 0th item in the yValuesMinusMean array, and -2 is the 0th item in the array within xValuesMinusMean. So -5 * -2.
My next steps would be to do something like this:
xValuesMinusMean.forEach(element => {
for(let i = 0; i < xValuesMinusMean.length; i++) {
let product = (newCategoryArray[i] * xValuesMinusMean[i]);
total += product;
};
});
However, it yields the following: sumOfXTimesYValues = 352, which isn't correct. How would I be able to achieve the end goal?
END GOAL: sumOfXTimesYValues = [17, 22, ...]
Create a generic function for computing a scalar product (you've already got it):
function scalarProduct(a, b) {
let res = 0;
for(let i = 0; i < a.length; i++) {
res += a[i] * b[i];
}
return res;
}
and then map it over your matrix (array of vectors):
result = xValuesMinusMean.map(vec => scalarProduct(vec, yValuesMinusMean))
You can have one reduce function where you will take product of arrays and store it in accumulator.
const val =[ [ 2.75,3.75,6.75,5.25 ], [-2,-1,2,1]];
const yvalues = [-5, -4, -1, 10];
console.log(val.map(o=>o.reduce((a,e,i)=>a+=e*yvalues[i],0)));
Looks like your calculation is not correct first set of arrays will also return 22.
Live Demo :
const yValuesMinusMean = [-5, -4, -1, 10];
const xValuesMinusMean = [[2.75, 3.75, 6.75, 5.75], [-2, -1, 2, 1]];
const finalArr = [];
xValuesMinusMean.forEach(arr => {
let cal = 0;
arr.forEach((item, index) => {
cal += item * yValuesMinusMean[index]
});
finalArr.push(cal);
});
console.log(finalArr); // [22, 22]
let items = ['Tom','Bill','Kim'];
let result = items.reduce((str, item) => str + '<'.concat(item).concat('>'),"");
console.log(result);
May I ask what the ending "" does to the code?
It's not related to concat, it's related to reduce. It's the second argument to reduce, which sets the initial value of the accumulator. E.g., it "seeds" the accumulation, so it's often called the "seed value" or just "seed."
Without that argument, the first call to the callback would get the entries at indexes 0 and 1 as its first two arguments. With that argument, the first callback receives "" as its first argument and the entry at index 0 as its second argument.
Side note:
It's probably worth noting that that use of concat probably isn't the best way to do what that callback is trying to do. The author of that code is mixing string concatenation via + with concat, which is a bit odd. I'd use one or the other, or a template literal:
Using +:
let items = ['Tom','Bill','Kim'];
let result = items.reduce((str, item) => str + '<' + item + '>', "");
console.log(result);
Using concat:
let items = ['Tom','Bill','Kim'];
let result = items.reduce((str, item) => str.concat('<', item, '>'), "");
console.log(result);
Using a template literal:
let items = ['Tom','Bill','Kim'];
let result = items.reduce((str, item) => `${str}<${item}>`, "");
console.log(result);
It's the second argument to reduce as the initial value for accumulator.
Understand this way - With a single example
// Add all numbers in arr
const numbers = [1, 2, 3, 4]
let sum = 0 // this is the initial value
for (let n of numbers)
sum += n
console.log(sum)
// Again add all numbers in arr using reduce
const numbers = [1, 2, 3, 4]
let sum = 0
sum = numbers.reduce((accumulator, currentValue) => {
return accumulator + currentValue
}, sum)
/**
* First round - accu = 0, currVal = 1 => accu = 1
* Second round - accu = 1, currVal = 2 => accu = 3
* Third round - accu = 3, currVal = 3 => accu = 6
* Fourth round - accu = 6, currVal = 4 => accu = 10
* Returns accu = 10
*/
console.log(sum)
// Reduce takes a callback
// Accumulator will get the initial value using sum
// currentValue is the each iteration value
Internally reduce returns accumulator + currentValue and save it to accumulator each iterate.
After reading the docs on map method,I still cannot get this to work.
I am trying to use map to get the average of every pair of numbers in an array.Please help me understand whats wrong.
function getAverage(num1,num2){return Math.ceil((num1+num2)/2)};
function a(input){ var b = input.map(getAverage(num1,num2)); return b; }
a([1,2,3,4]) //error num1 is not defined
//expected [2,4]
map projects a function to each element of a list/array, it simply "maps" a function over all the items.
[1, 2, 3].map(function (number) { return number + 1; });
// -> [2, 3, 4]
Therefor, first you need to have pairs of items in your "input" array, so it looks like this:
var numberPairs = [[1, 2], [3, 4]]
Until now, all you have are just single numbers but no pairs.
After conversion, you can use map like this:
numberPairs.map(function (pair) {
return Math.ceil((pair[0] + pair[1]) / 2);
});
This will give:
[2, 4]
as a result.
You can't calculate the average using a map. A mapping pass a function to each element and then returns an array with the same shape. That is not the case, you want to get a value from an array, and you can use the reduce method for that.
// adds two number
const adder = (a,b) => a + b;
// reduces the array adding all numbers and divides
// by the array length
const getAverage = (arr) => arr.reduce(adder)/arr.length;
// outputs 2.5
console.log(getAverage([1,2,3,4]))
You can use reduce() instead of map() to aggregate averages of every n values in the array:
const sum = array => array.reduce((a, b) => a + b, 0)
const getAverage = n => (averages, value, index, array) => index % n === 0
? [...averages, Math.ceil(sum(array.slice(index, index + n)) / n)]
: averages
const result = [1, 2, 3, 4].reduce(getAverage(2), [])
console.log(result)
The JavaScript filter function not converting the item to integer by using the parseInt. Because of that string concatenation is going on rather than adding the values when used the filtered array in reduce function.
var numbers = ['1', 2, 3, 4,'hello'];
var intArray=numbers.filter(num => **parseInt(num)**);
var sum=intArray.reduce((tot, b) => tot+b,0);
The trick is to first filter out non int values and then convert all of them to int
filter with isNaN would eliminate hello and map with parseInt will convert strings o number to int
var numbers = ['1', 2, 3, 4, 'hello'];
var intArray = numbers
.filter(num => !isNaN(num)).map(x => parseInt(x))
Your filter is filtering out the items that cannot be coerced to a number, but the items are still not necessarily numbers - convert them to numbers before using + with them, perhaps with .map:
var numbers = ['1', 2, 3, 4, 'hello'];
var intArray = numbers
.filter(num => parseInt(num))
.map(Number);
var sum = intArray.reduce((tot, b) => tot + b, 0);
console.log(sum);
Or, you can do it all at once with reduce and isNaN:
var numbers = ['1', 2, 3, 4, 'hello'];
var sum = numbers.reduce((tot, b) => {
if (isNaN(b)) return tot;
return tot + Number(b);
}, 0);
console.log(sum);
You can also sum them in one reduce and skip the filter stage where "1" gets passed as valid value (which as pointed out already is the issue) etc.
var numbers = ['1', 2, 3, 4,'hello'];
const result = numbers.reduce((r,c) => (+r||0) + (+c||0))
console.log(result)
I have an array of numbers newArr, whose length I use to create an array filled with zeros zeroArr
const newArr = [1,3,5,8,9,3,7,13]
const zeroArr = Array.from(Array(newArr.length), () => 0);
console.log(zeroArr) // [0,0,0,0,0,0,0,0]
Now, I need to replace the last index value 0 to 10 so it should look like this:
const result = [0,0,0,0,0,0,0,10]
How to do this?
You can replace the last item in the array like this:
result[result.length-1] = 10;
Demo in Stack Snippets
const newArr = [1,3,5,8,9,3,7,13];
const zeroArr = Array.from(Array(newArr.length), () => 0);
let result = zeroArr.slice(); // To create a copy
result[result.length-1] = 10;
console.log(result);
You could use Array#map and check if the last element, then return 10 otherwise zero.
var array = [1, 3, 5, 8, 9, 3, 7, 13],
copy = array.map((_, i, a) => 10 * (i + 1 === a.length));
console.log(copy);
another option could be:
const newArr = [1,3,5,8,9,3,7,13]
const zeroArr = newArr.map(()=>0);
const arrWith10 = [...zeroArr.slice(0,-1), 10]
console.log(zeroArr) // [0,0,0,0,0,0,0,0]
console.log(arrWith10) // [0,0,0,0,0,0,0,10]
You have to copy the values in the newArr to zeroArr first then push the value 10 to the index you wanted in ZeroArr. And Print to values in 'ZeroArr'