'array.reduce()' function unrecognised - javascript

The error is Uncaught TypeError: data.reduce is not a function and is shown to appear on the commented line here:
function stdDev(values) {
var avg = average(values);
var squareDiffs = values.map((value) => {
return (value - avg) * (value - avg);
});
return Math.sqrt(average(squareDiffs));
}
function average(data) {
var sum = data.reduce((sum, value) => {//this is the line in question
return sum + value;
});
return sum / data.length;
}
$("#std").html(stdDev(12,21,32,34,18,26));
This code resides within a <script> tag in a .ejs document. I have no idea why a standard function would not be available, any help would be greatly appreciated.

You need to put the values into an array in the call to stdDev
$("#std").html(stdDev([12,21,32,34,18,26]));

Array.reduce works on array, it seems you are passing an object instead of an array,
change your method calling code as,
$("#std").html(stdDev([12,21,32,34,18,26]));

You pass the numbers as a series of parameters, and not as an array. The values is actually the 1st number you've passed, and not an array. Use rest parameters to collect all numbers to an array:
function stdDev(...values) {
const avg = average(values);
const squareDiffs = values.map((value) => (value - avg) * (value - avg));
return Math.sqrt(average(squareDiffs));
}
function average(data) {
const sum = data.reduce((sum, value) => sum + value);
return sum / data.length;
}
console.log(stdDev(12,21,32,34,18,26));

you call stdDev with a list of numbers:
stdDev(12,21,32,34,18,26)
but the declaration expects an array:
function stdDev(values) {
so when you call
var avg = average(values);
you're passing 12, which is not an array.

Related

Why is my function working when called by itself but not when I call it with another function? (Beginner javascript question)

I am working on some coding challenges (I am still a beginner). I was able to make both of these functions work, but when I try to call them together my second function just returns zero..
Both functions take in two parameters (or more). The first function counts the numbers between the two paramters and returns them in a string (1, 5) => [1,2,3,4,5] and the second sums them together (1,10) => 55. Any reason why these work individually but not together?
Thanks in advance!
`let range = (start, end) => {
numbers = [];
for(i = start; i<end+1; i++) {
if(i>=start){
numbers.push(i);
if (i>=end) {
console.log(numbers);
}
}
}
}
function sum(start, ...add){
let sumCounter = 0;
for(i = start; i<=add; i++) {
sumCounter += i;
}
return sumCounter;
}
console.log(sum(1,10)); //second function works
console.log(sum(range(1, 10))); //first function works, not second function `
There are a lot of things going on here. First make sure that you’re returning a value in the first function, and not just printing to the console. Second, when you say “if(i>=end)” that will always be true, so it isn’t needed. Also instead of saying “if(I>=end)” you can put “I==end” or just put the following code after the for loop. I would suggest that you return the numbers, and take that as a parameter for your sum function. I hope you’re able to follow all of that!
Here is a working option:
function range(start, end) {
var numbers = [];
for (i=start;i<end+1;i++) {
numbers.push(i)
}
return numbers;
}
console.log("Sum: " + range(5, 10).reduce((a,b) => a + b, 0));
Or this might be easier to understand:
function range(start, end) {
var numbers = [];
for (i=start;i<end+1;i++) {
numbers.push(i)
}
return numbers;
}
function sum(nums) {
var sum = 0;
for (i=0;i<nums.length;i++) {
sum += nums[i];
}
return sum;
}
console.log("Sum: " + sum(range(5, 10)));

Add Sum of all values from locators of a web table, method results values of only first two locators

I want to add all the values of locators from a web table but it is adding only first two values. here is my method declaration below.
exports.GetMonthsFWSeasonSTDPreMkdValues = () => {
var total_value;
for(var month_index = 9; month_index <= 18 ; month_index++){
const elm_xpath = utils.GetXpathForSubCategory(chosen_season_index, month_index);
return browser.element(by.xpath(elm_xpath)).getText().then(function(response_total_months_index_values){
total_value += response_total_months_index_values;
console.log('total value' ,total_value);
});
}
};
The root case is you use return inside For loop, thus the loop only be iterated one time.
And another hiddened code issue is javascript closure issue, the For loop execute as Sync, but the getText() inside loop execute as Async.
If you remove keyword return, the browser.element(by.xpath(elm_xpath)).getText() will repeat use the elm_xpath of month_index=18
exports.GetMonthsFWSeasonSTDPreMkdValues = () => {
var promises = [];
for(var month_index = 9; month_index <= 18 ; month_index++){
const elm_xpath = utils.GetXpathForSubCategory(chosen_season_index, month_index);
promises.push(element(by.xpath(elm_xpath)).getText());
}
return Promise.all(promises).then(function(data){
return data.reduce(function(accumulator, currentValue){
return accumulator + currentValue * 1;
}, 0);
});
};
//Remind: this function return a promise.

How to ilterate with recursive function (javascript)

function numberSum(num) {
var str = num.toString();
var arrNum = str.split('').map(Number);//arrNum = [1, 2, 3];
//For-looping
var result = 0;
for (var i = 0; i < arrNum.length; i++) {
result = result + arrNum[i];
}
return result;
}
console.log(numberSum(22222)); // 2 + 2 + 2 + 2 + 2 = 10
I did this with For-looping and then iterate it. The question is, how do i did the same but with Recursive Function?
You could use only the first element for addition and call the function with the rest of the array again.
In this case, a check is made for the length, this returns either 0 if the array has no items or the item count, then a shift is made which returns the first item of the array. Additionaly the function is called again with the reduced array.
function iter(array) {
return array.length && array.shift() + iter(array);
// ^^^^^^^^^^^^ exit condition,
// if zero, return zero,
// otherwise return the
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ iteration part
// return the first value and
// call recursion again
}
function numberSum(v) {
function iter(array) {
return array.length && array.shift() + iter(array);
}
return iter(v.toString().split('').map(Number));
}
console.log(numberSum(22222)); // 2 + 2 + 2 + 2 + 2 = 10
For the input you have (22222) your function is a practical solution. If you want a function that takes a number and adds itself together a certain number of times you can simply do this...
function sums(a, b) {
return a * b;
}
sums(2, 5);
//=> 10
But if you really require an example of a recursive function to do this the following will achieve the same result...
var num = 2;
var iterate = 5;
function sums(n, count, total) {
if (count === 0) {
return total;
} else {
return sums(n, --count, total+n);
}
}
console.log(sums(num, iterate, 0));
//=> 10
Hope that helped. :)
(See this blog post on JavaScript recursion by integralist).

Multiply all function params

I'm trying to create a function that will multiply all parameters passed into it. The amount of parameters that can be passed to the function can vary. So far I have this
var multiply = function () {
var i, sum = 0;
for (i = 0; i < arguments.length; i++) {
sum *= arguments[i];
}
return sum;
};
When I call it like this - multiply(10, 5, 5) - It returns 0 when the answer should be 250 (10 x 5 x 5). What am I doing wrong here?
Multiplying any number with 0 is 0.
So set var sum = 1;
You could do it also by using 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.
It does not really have a benefit over the for loop except that you make clear that you want to accumulate the value by using a function that is intended for this.
var multiply = function () {
return Array.prototype.reduce.call(arguments, function(a, b) {
return a * b;
});
};
You need to use the Array.prototype.reduce.call construct because arguments is only an array like object it most environments.
Since ES6 the answer would be =>
const multiply = (..args) => args.reduce((accum, val) => accum * val, 1);

How can I get this javascript function to call itself?

As of right now my sum function looks like the code below. It works and returns the sum of the consecutive calls. But how can I make this work without the empty parenthesis at the end? Like so theSum(5)(4)(3) which returns 12.
function theSum(x) {
var total = x;
function rec(y) {
if (y === undefined) return total;
total += y;
return rec;
};
return rec;
}
console.log(theSum(5)(4)(3)()); // 12
Here is a suggestion utilizing a toString method:
function theSum(x) {
var total = x;
function rec(y) {
total += y;
return rec;
};
rec.toString = function() { return total; }
return rec;
}
alert(theSum(5)(4)(3));
console.log(parseInt(theSum(5)(4)(3)));
Note however that you need to convert the returned reference to a string in some way so that you see the result.
This is not possible. A function cannot return a function and an integer. You can make theSum(5, 4, 3) = 12 or theSum([5, 4, 3]) = 12.
Closures and JavaScript duck typing to the rescue:
function NumSumFun(initial){
function NumSumNext(num) {
initial+= num;
return NumSumNext;
}
NumSumNext.valueOf = function () { return initial; }
return NumSumNext;
}
var x = NumSumFun(10)(29); // ==> function 39
x + 1; // ==> 40
So whats happening. It returns a function but the function has a valueOf property that has access to the accumulated value so the function acts as a number when used as a number.

Categories