Multiply all function params - javascript

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);

Related

Why random number doesn't change in every iteration?

I want to set a matrix with random numbers.
I used a function to create a 0 matrix first, then loop through every cell and assign a random number to it.
function getRandomArbitrary(min, max) {
let value = Math.random() * (max - min) + min;
if (value === 0)
return getRandomArbitrary(min, max);
return value;
}
function matrix(m, n, d) {
return Array.apply(null, new Array(m)).map(
Array.prototype.valueOf,
Array.apply(null, new Array(n)).map(
function() {
return d;
}
)
);
}
let weight_1 = matrix(4, 3, 0);
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 3; j++) {
weight_1[i][j] = getRandomArbitrary(-1, 1);
}
}
console.table(weight_1)
When I run the code, I get the following output.
As can be seen in the picture, the random value changes only when i changes. Is this related to JS being asynchronous or because random numbers generated by Math.random has a relation to timestamp?
Array.prototype.valueOf is Object.prototype.valueOf, and simply returns the receiver value (this argument). It does not create a copy of the array - so you are mapping to an outer array that contains the same inner array at every index. Instead, use
function matrix(m, n, d) {
return Array.apply(null, new Array(m)).map(
function() {
return Array.apply(null, new Array(n)).map(
function() {
return d;
}
);
}
);
}
or the simpler and more conventionally formatted
function matrix(m, n, d) {
return Array.from({length: m}, () =>
Array.from({length: n}, () =>
d
)
);
}
Also you might want to make d a callback function and call it, so that you create your matrix directly by matrix(4, 3, () => getRandomArbitrary(-1, 1)) instead of initialising it with 0 and then looping it to change the values.

Higher-order function

I have an exercise about JavaScript. This exercise requires me to use higher-order functions. I have managed to specify some of the functions so far, but when I try to execute the code, the result does not seem to work properly. I have some images to give you an idea, hopefully, you can help me correct this.
The thread is: Write the function loop(loops, number, func), which runs the given function the given number of times. Also write the simple functions halve() and square().
This is my code:
function loop(loops, number, func) {
var loops = function(n) {
for (var i = 0; i < n; i++) {
if (i < 0) {
console.log('Programme ended')
}
if (i > 0) {
return n;
}
}
}
}
var halve = function(n) {
return n / 2
}
var square = function(n) {
return n ** 2;
}
console.log(halve(50));
console.log(loop(5, 200, halve));
console.log(loop(3, 5, square));
console.log(loop(-1, 99, halve));
Your current loop function declares an inner function and then exits. Ie, nothing actually happens -
function loop(loops,number,func){
// declare loops function
var loops= function(n){
// ...
}
// exit `loop` function
}
One such fix might be to run the supplied func a number of times in a for loop, like #code_monk suggest. Another option would be to use recursion -
function loop (count, input, func) {
if (count <= 0)
return input
else
return loop(count - 1, func(input), func)
}
function times10 (num) {
return num * 10
}
console.log(loop(3, 5, times10))
// 5000
so first things first: Higher-Order functions are functions that work on other functions.
The reason why you get undefined is because you are calling a function which doesn't return anything.
function x(parameter){
result = parameter + 1;
}
// -> returns undefined every time
console.log(x(5));
// -> undefined
function y(parameter){
return parameter+1;
}
// -> returns a value that can be used later, for example in console.log
console.log(y(5));
// -> 6
Second, you are using n for your for loop when you should probably use loops so it does the intended code as many times as "loops" indicates instead of the number you insert (i.e. 200, 5, 99).
By having the "console.log" inside a loop you may get a lot of undesired "programme ended" in your output so in my version I kept it out of the loop.
The other two answers given are pretty complete I believe but if you want to keep the for loop here goes:
function loop(loops, number, func){
if(loops>0){
for(let i = 0; i< loops; i++){ // let and const are the new ES6 bindings (instead of var)
number = func(number)
}
return number
}
else{
return "Programme ended"
}
}
function halve(n) { // maybe it's just me but using function declarations feels cleaner
return n / 2;
}
function square(n) {
return n ** 2;
}
console.log(halve(50));
console.log(loop(5, 200, halve));
console.log(loop(3, 5, square));
console.log(loop(-1, 99, halve));
Here's one way
const loop = (loops, n, fn) => {
for (let i=0; i<loops; i++) {
console.log( fn(n) );
}
};
const halve = (n) => {
return n / 2;
};
const square = (n) => {
return n ** 2;
};
loop(2,3,halve);
loop(4,5,square);

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)));

Why are for...of and for loop behaving differently?

Just was performing simple task in JS which was to take integer as an input, divide it into single digits and multiply them ignoring all zeros in it.
I have solved it but had some troubles which were simply solved by changing the loop. I am just curious why the code did not work properly with the for loop and started to work as I it for for of loop. I could not find out the answer by my self. If somebody could tell where I am wrong.
First one works as intended, second one always returns 1.
function digitsMultip1(data) {
var stringg = data.toString().split("", data.lenght);
for (let elements of stringg) {
if (elements != 0) {
sum = parseInt(elements) * sum
} else {
continue
};
}
return sum;
}
console.log(digitsMultip1(12035))
function digitsMultip2(data) {
var sum = 1;
var stringg = data.toString().split("", data.lenght);
for (var i = 0; i > stringg.lenght; i++) {
if (stringg[i] != 0) {
sum = parseInt(stringg[i]) * sum
} else {
continue
};
}
return sum;
}
console.log(digitsMultip2(12035))
There is no big difference. for..of works in newer browsers
The for...of statement creates a loop iterating over iterable objects, including: built-in String, Array, Array-like objects (e.g., arguments or NodeList), TypedArray, Map, Set, and user-defined iterables. It invokes a custom iteration hook with statements to be executed for the value of each distinct property of the object.
Several typos
length spelled wrong
> (greater than) should be < (less than) in your for loop
Now they both work
function digitsMultip1(data) {
var sum=1, stringg = data.toString().split("");
for (let elements of stringg) {
if (elements != 0) {
sum *= parseInt(elements)
} else {
continue
};
}
return sum;
}
console.log(digitsMultip1(12035))
function digitsMultip2(data) {
var sum = 1, stringg = data.toString().split("");
for (var i = 0; i < stringg.length; i++) {
if (stringg[i] != 0) {
sum *= parseInt(stringg[i])
} else {
continue
};
}
return sum;
}
console.log(digitsMultip2(12035))
You might want to look at reduce
const reducer = (accumulator, currentValue) => {
currentValue = +currentValue || 1; return accumulator *= currentValue
}
console.log(String(12035).split("").reduce(reducer,1));

'array.reduce()' function unrecognised

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.

Categories