I would like to know how I can sum an algebraic sum.
For example, I have a function with two parameters:
function sumAlga(paramA, paramB) {
return paramA + paramB;
}
How I should do it for algebraic sum in JavaScript?
Incorrect Code
As "don't angry me" has said in the comments, you have return paramA + paramBM not return paramA + paramB so that should fix that (assuming that was an unintentional typo, correct me if we're wrong).
More than two arguments
To accomplish this with any number of parameters you could do the following,
function algebraicSum() {
var sum = 0;
for (var i = 0; i < arguments.length; ++i) {
sum += arguments[i];
}
return sum;
}
Usage
algebraicSum(1,2,3,4) = 10;
algebraicSum(1,-2,3) = 2;
you can try something like this:
var age_child = parseInt(10);
var age_gap = parseInt(10);
alert(age_child+age_gap);
Unlike Java or C, which are strongly typed languages, Javascript is smart and hence is also called a weakly typed language. You don't have to specify the data-type of your variable while declaring it. but in this case, you should specify the data type to match with your operations.
The main purpose is to have a function which could be used as callback for Array#reduce, for example.
An array with values could be summed by taking the function and a start value of zero (this is necessary, if an empty array or an array with only one item is supplied).
function add(a, b) {
return a + b;
}
console.log([1, 2, -5].reduce(add, 0));
console.log([1].reduce(add, 0));
console.log([].reduce(add, 0));
The following code uses an arrow function, which has some differences to the standard function, but is sometimes shorter.
const add = (a, b) => a + b;
console.log([1, 2, -5].reduce(add, 0));
console.log([1].reduce(add, 0));
console.log([].reduce(add, 0));
Related
I have a dice-rolling bot that spits out results via var roll = new Roll('4#2d20+3'). That constructor makes objects with properties parsed out of the string argument, which resembles this:
aRoll = {
text: '4#2d20+3',
times: 4,
dice: 2,
sides: 20,
modifier: 3,
roll: function() {...}
}
The roll() method should use the object's properties to generate an array of results. This is an exercise to learn what's new in JavaScript, so I'm curious how best to accomplish this.
Old, procedural way:
this.roll = function() {
var total = 0;
for (var i=0; i < this.dice; i++) {
total += Math.floor(Math.random() * this.sides) + 1;
}
return total;
}
My attempt at new Array functional iteration:
this.roll = () => Array(this.dice).fill(0).reduce(state => {
result + Math.floor(Math.random() * state.sides) + 1;
}, this);
This sorta works, but Array(x).fill(0).reduce(... is an ugly hack, and passing this in as state seems like a sign I'm doing the wrong thing.
Is there an Array method I should use instead? Or is the for loop still the cleanest way to accomplish this?
One way to repeat a function n times is
Array.from(Array(n), fn)
To make all of this more readable, you could define, for example
let times = (n, fn) => Array.from(Array(n), fn);
let rand = n => Math.floor(Math.random() * n) + 1;
let sum = a => a.reduce((x, y) => x + y);
and then
roll = function() {
return sum(
times(this.dice,
rand.bind(0, this.sides)));
}
I think I figured out how this “should” be done.
The first issue is straightforward: do not use arrow functions as methods:
An arrow function does not create its own this context, so this has its original meaning from the enclosing context.
this is the whole point of object-orientation, so breaking it is a bad idea. Passing this as map()’s second argument was indeed a code smell.
The second issue: instead of abusing reduce()’s initial value parameter with this to fake a context object, use a closure:
function roll(sides) {
return (total) => {
total + Math.floor(Math.random() * sides) + 1;
};
}
someArray.map(roll(this.sides));
When you pass callbacks as arguments, but need to dynamically give them data that callers don’t provide, closures are the classic solution.
As for the third issue, populating an array the size of an object property, in order to call a function that many times…
There is no built-in boilerplate way. :•) #georg kindly provided a clean implementation of a times() function that reminds me of Ruby’s Number.times(), if you’re interested.
I'm a new student who's learning Javascript for the first time. This time I'm trying to better grasp the concepts of converting numbers into strings, storing them in arrays, converting them back to numbers, and adding.
In this assignment, I'm trying to write a function that takes the individual digits of a number and adds them together.
So for example, the function would take (95) and return 14. Or given (135), would return 9.
Here's what I got so far:
var addDigits = function(num) {
var newNum = num.toString();
newNum = newNum.split('');
var sum = 0;
var thirdNum = newNum.forEach(function(x) {
parseInt(x);
sum + x };
};
I'm fully aware that is not very good code, but could anyone give me any tips? Should I be using parseInt or Number?
You're pretty close. Few things though. array.forEach doesn't return anything. It's used for creating side effects (increasing sum would be considered a side effect of the function you're passing into the forEach). So setting the forEach to a variable doesn't accomplish anything. parseInt does return something, so you need to set it to a variable. And you also want to increase sum by the parsed integer plus the sum you already have. You can look into the += operator for that if you wish. Last, you need to return a value from the function itself! As it is, if you did var added = addDigits(123), added would be undefined. So finish it off with a return statement.
After you've got the grasp of that, I'd suggest looking into array.reduce to replace array.forEach since it's perfect for a problem such as this.
var addDigits = function(string) {
newNum = string.split('');
var sum = 0;
for(var i = 0 ; i < newNum.length ; i++) sum += parseInt(newNum[i]);
return sum;
};
console.log(addDigits("1234"));
Maybe this will be better:
function getDigitsSum(number) {
var charArray = (number + '').split('');
var sum = 0;
charArray.forEach(function(item) {
sum += parseInt(item)
})
return sum;
}
Number() performs type conversion, whereas parseInt() performs parsing.
What is the difference between parseInt() and Number()?
In this situation, it doesn't make a difference since the strings are proper integers.
Here's how I would do it.
var addDigits = function(num) {
var newNum = num.toString().split('');
var sum = newNum.map(Number).reduce((prev, curr) => prev + curr);
return sum;
};
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
Assuming your input will always be an integer string, consider the following function:
var addDigits = function(strInt) {
var int = function(x) {
return parseInt(x,10) //10 is the radix
}
return strInt.split('').map(int).reduce(function(a,b){return a+b});
}
The function tied to var int will ensure that the provided integer string be parsed into its corresponding base 10 integer (notice the difference in type, which can be validated with Javascript's built-in typeof() function). The return will first .split the string, .map the int function against every value within the given string, and then apply whatever function you have within .reduce against an accumulated value - in this case, simply adding against each member of the array.
What's the best way to indicate a function uses the 'arguments' object?
This is obviously opinion based but are there any conventions? When would it be better to use an array of arguments?
Some examples:
// Function takes n arguments and makes them pretty.
function manyArgs() {
for (var i = 0; i < arguments.length; i++)
console.log(arguments[i]);
}
function manyArgs( /* n1 , n2, ... */ )
function manyArgs(n1 /*, n2, ... */ )
function manyArgs(argArray)
I never use variadic arguments in JavaScript. There are many better ways of structuring your code. For example, I would rewrite your code as follows:
[1,2,3,4,5].forEach(log); // instead of manyArgs(1,2,3,4,5);
function log(a) {
console.log(a);
}
It's clear and concise.
Another example, if you want to find the sum of a list of numbers in JavaScript:
[1,2,3,4,5].reduce(add, 0); // instead of add(1,2,3,4,5);
function add(a, b) {
return a + b;
}
There are so many useful abstractions available to structure your code that I don't see the benefit of using variadic arguments at all.
I do however use the arguments object for default values:
function foo(a,b,c) {
switch (arguments.length) {
case 0: a = "default argument for a";
case 1: b = "default argument for b";
case 2: c = "default argument for c";
}
// do something with a, b & c
}
Hence my advise to you would be to not use variadic arguments at all. Find a better abstraction for your code. I've never encountered the need to use variadic arguments in the 8 years that I have been programming in JavaScript.
Edit: I would advocate using a more functional approach to writing code. We can use currying to make code more succinct:
function curry(func, length, args) {
switch (arguments.length) {
case 1: length = func.length;
case 2: args = [];
}
var slice = args.slice;
return function () {
var len = arguments.length;
var a = args.concat(slice.call(arguments));
if (len >= length) return func.apply(this, a);
return curry(func, length - len, a);
};
}
Using curry we can rewrite the sum example as follows:
var reduce = curry(function (func, acc, a) {
var index = 0, length = a.length;
while (index < length) acc = func(acc, a[index++]);
return acc;
});
var sum = reduce(add, 0);
sum([1,2,3,4,5]); // instead of add(1,2,3,4,5);
function add(a, b) {
return a + b;
}
Similarly for Math.max and Array.prototype.concat:
var reduce1 = curry(function (func, a) {
if (a.length === 0)
throw new Error("Reducing empty array.");
return reduce(func, a[0], a.slice(1));
});
var maximum = reduce1(max);
maximum([1,2,3,4,5]); // instead of Math.max(1,2,3,4,5);
function max(a, b) {
return a > b ? a : b;
}
var concat = reduce(function (a, b) {
return a.concat(b);
}, []);
concat([[1,2],[3,4],[5,6]]) // instead of [1,2].concat([3,4],[5,6])
As for Array.prototype.push, because it mutates the input array instead of creating a new one, I prefer using array.concat([element]) instead of array.push(element):
var push = reduce(function (a, e) {
return a.concat([e]);
});
push([1,2,3], [4,5]); // instead of [1,2,3].push(4, 5)
So what are the advantages of writing code this way:
Currying is awesome. It allows you to create new functions from old ones.
Instead of using variadic arguments you are passing arrays to functions. So you don't need any special way to indicate that the function uses arguments.
Suppose you have to find the sum of an array named array. Using this method you just do sum(array). If you use variadic arguments then you would need to do add.apply(null, array).
Suppose you want to find the sum of a, b & c. All you need to do is sum([a,b,c]), as compared to add(a, b, c). You need to put in the extra [] brackets. However doing so makes your code more understandable. According to the zen of python “explicit is better than implicit”.
So these are some of the reasons I never use variadic arguments in my programs.
// Using ES6 syntax ...
var foo = function(/*...args*/){
// shim Array.from, then
var args = Array.from(arguments);
// or
var args = [].slice.call(arguments);
};
The clearest way is to use the spread operator available in ES6, CoffeeScript (where they are called "splats" and the three dots come after the identifer), and TypeScript (where they are called "rest parameters").
// Function takes n arguments and makes them pretty.
function manyArgs(...args) {
for (var i = 0; i < args.length; i++)
console.log(args[i]);
}
If you're in an environment where you can use them, of course. It is both better self-documenting, and avoids having to muck around with arguments.
Do you have any real-world example of the use of the second and third parameters for the callback to Array.prototype.some or Array.prototype.any?
According to MDN:
callback is invoked with three arguments: the value of the element, the index of the
element, and the Array object being traversed.
I've personally never used them.
I have been working for some time on the Javascript functional programming library, Ramda, and early on we made the controversial decision not to use the index and array parameters for other similar functions that we created. There are good reasons for this, which I don't need to get into here, except to say that for some functions, such as map and filter, we find such extra parameters do have some occasional utility. So we offer a second function which supplies them to your callback. (For example, map.idx(yourFunc, list).)
But I've never even considered doing so for some or every. I never imagined a practical use of these. But there is now a suggestion that we include these functions in our list of index-supporting ones.
So my question again is whether you have ever found an actual, live, real-world callback function to some or every which actually needs these parameters? If so, could you describe it?
Answers of "No, I never do," would be helpful data too, thanks.
Quick search in our code:
function isAscending(array) {
return array.every(function (e, idx, arr) {
return (idx === 0) ? true : arr[idx-1] <= e;
});
}
I could imagine something like the following code to check whether an array is duplicate-free:
….every(function(v, i, arr) {
return arr.indexOf(v, i+1) == -1;
})
Where … is a complex expression so that you'd really have to use the arr parameter - which is no more an issue if you'd properly factor out the functionality in an own function that takes the array as an argument.
The second parameter can be useful sometimes, but I support your position that it is rather seldom used.
Yes, they are helpful
These extra parameters actually do come in handy, but not that often.
In the recent past, I had written a function to find all the permutations of a list of elements:
permute :: [a] -> [[a]]
For example permute [1,2,3] would be:
[ [1,2,3]
, [1,3,2]
, [2,1,3]
, [2,3,1]
, [3,1,2]
, [3,2,1]
]
The implementation of this function is quite simple:
If the input is [] then return [[]]. This is the edge case.
If the input is say [1,2,3]:
Add 1 to every permutation of [2,3].
Add 2 to every permutation of [1,3].
Add 3 to every permutation of [1,2].
Of course, the function is recursive. In JavaScript, I implemented it as follows:
var permute = (function () {
return permute;
function permute(list) {
if (list.length === 0) return [[]]; // edge case
else return list.reduce(permutate, []); // list of permutations
// is initially empty
}
function permutate(permutations, item, index, list) {
var before = list.slice(0, index); // all the items before "item"
var after = list.slice(index + 1); // all the items after "item"
var rest = before.concat(after); // all the items beside "item"
var perms = permute(rest); // permutations of rest
// add item to the beginning of each permutation
// the second argument of "map" is the "context"
// (i.e. the "this" parameter of the callback)
var newPerms = perms.map(concat, [item]);
return permutations.concat(newPerms); // update the list of permutations
}
function concat(list) {
return this.concat(list);
}
}());
As you can see, I have used both the index and the list parameters of the permutate function. So, yes there are cases where these extra parameters are indeed helpful.
However, they are also problematic
However these superfluous arguments can sometimes be problematic and difficult to debug. The most common example of this problematic behavior is when map and parseInt are used together: javascript - Array#map and parseInt
alert(["1","2","3"].map(parseInt));
As you can see it produces the unexpected output [1,NaN,NaN]. The reason this happens it because the map function calls parseInt with 3 arguments (item, index and array):
parseInt("1", 0, ["1","2","3"]) // 1
parseInt("2", 1, ["1","2","3"]) // NaN
parseInt("3", 2, ["1","2","3"]) // NaN
However, the parseInt function takes 2 arguments (string and radix):
First case, radix is 0 which is false. Hence default radix 10 is taken, resulting in 1.
Second case, radix is 1. There is no base 1 numeral system. Hence we get NaN.
Third case, radix is 2 which is valid. However there's no 3 in base 2. Hence we get NaN.
As you see, superfluous arguments can cause a lot of problems which are difficult to debug.
But, there is an alternative
So these extra arguments are helpful but they can cause a lot of problems. Fortunately, there is an easy solution to this problem.
In Haskell if you want to map over a list of values and the indices of each value then you use do it as follows:
map f (zip list [0..])
list :: [Foo]
[0..] :: [Int]
zip list [0..] :: [(Foo, Int)]
f :: (Foo, Int) -> Bar
map f (zip list [0..]) :: [Bar]
You could do the same thing in JavaScript as follows:
function Maybe() {}
var Nothing = new Maybe;
Just.prototype = new Maybe;
function Just(a) {
this.fromJust = a;
}
function iterator(f, xs) {
var index = 0, length = xs.length;
return function () {
if (index < length) {
var x = xs[index];
var a = f(x, index++, xs);
return new Just(a);
} else return Nothing;
};
}
We use a different map function:
function map(f, a) {
var b = [];
if (typeof a === "function") { // iterator
for (var x = a(); x !== Nothing; x = a()) {
var y = f(x.fromJust);
b.push(y);
}
} else { // array
for (var i = 0, l = a.length; i < l; i++) {
var y = f(a[i]);
b.push(y);
}
}
return x;
}
Finally:
function decorateIndices(array) {
return iterator(function (item, index, array) {
return [item, index];
}, array);
}
var xs = [1,2,3];
var ys = map(function (a) {
var item = a[0];
var index = a[1];
return item + index;
}, decorateIndices(xs));
alert(ys); // 1,3,5
Similarly you can create decorateArray and decorateIndicesArray functions:
function decorateArray(array) {
return iterator(function (item, index, array) {
return [item, array];
}, array);
}
function decorateIndicesArray(array) {
return iterator(function (item, index, array) {
return [item, index, array];
}, array);
}
Currently in Ramda you have two separate functions map and map.idx. The above solution allows you to replace map.idx with idx such that:
var idx = decorateIndices;
var arr = decorateArray;
var idxArr = decorateIndicesArray;
map.idx(f, list) === map(f, idx(list))
This will allow you to get rid of a whole bunch of .idx functions, and variants.
To curry or not to curry
There is still one small problem to solve. This looks ugly:
var ys = map(function (a) {
var item = a[0];
var index = a[1];
return item + index;
}, decorateIndices(xs));
It would be nicer to be able to write it like this instead:
var ys = map(function (item, index) {
return item + index;
}, decorateIndices(xs));
However we removed superfluous arguments because they caused problems. Why should we add them back in? Two reasons:
It looks cleaner.
Sometimes you have a function written by somebody else which expects these extra arguments.
In Haskell you can use the uncurry function to solve this problem:
map (uncurry f) (zip list [0..])
list :: [Foo]
[0..] :: [Int]
zip list [0..] :: [(Foo, Int)]
f :: Foo -> Int -> Bar
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f :: (Foo, Int) -> Bar
map (uncurry f) (zip list [0..]) :: [Bar]
In JavaScript the uncurry function is simply apply. It is implemented as follows:
function uncurry(f, context) {
if (arguments.length < 2) context = null;
return function (args) {
return f.apply(context, args);
};
}
Using uncurry we can write the above example as:
var ys = map(uncurry(function (item, index) {
return item + index;
}), decorateIndices(xs));
This code is awesome because:
Each function does only one job. Functions can be combined to do more complex work.
Everything is explicit, which is a good thing according to the Zen of Python.
There's no redundancy. There's only one map function, etc.
So I really hope this answer helps.
I am to write up some code using Javascript. Here is what we are to do:
"Implement a javascript Fibonacci numbers using closures. Specifically, write an function that stores two consecuitive Fibonacci numbers, initially 0 and 1. The function also defines and returns a nested function getNext(). The getNext() function updates the two stored Fibonacci numbers to the next two Fibonacci numbers and returns the current one. E.g. on the first call to getNext() the return value is 0, on the next call it is 1, then 1 again, then 2, etc."
I kind of understand this but not really. Could someone maybe help clarify? Thanks!
The basic idea behind closures is that, since closers bind all local data by value, you can use them to initialize and then modify variables that are only local to that "instance" of the generated function.
Since this seems like homework, I'm going to answer a different question using closures: Use closures to get perfect squares (1, 4, 9, etc.), one at a time.
function makeSquareIteratorFunction() {
var squareRoot = 1;
var getNext = function() {
// Calculate the number you need to return
var square = squareRoot * squareRoot;
// Apply side effects. In this case just incrementing the counter, but with
// Fibonacci you will need to be a little more creative :-)
// You might also prefer to do this first. Depends on your approach.
squareRoot = squareRoot + 1;
// Return the value
return square;
};
// Return the function object, which can then be called later
return getNext;
}
// Usage
var getNextSquare = makeSquareIteratorFunction();
alert(getNextSquare()); // 1
alert(getNextSquare()); // 4
alert(getNextSquare()); // 9
Now, it's worth pointing out that the local variables defined in the outer function (makeSquareIteratorFunction) are localized and bound to the closure. So if you call makeSquareIteratorFunction() multiple times, the later ones will be independent of the first one:
var getNextSquare1 = makeSquareIteratorFunction();
alert(getNextSquare1()); // 1
alert(getNextSquare1()); // 4
var getNextSquare2 = makeSquareIteratorFunction();
alert(getNextSquare2()); // 1 (!) because it's a new closure, initialized the same way
alert(getNextSquare1()); // 9 (!) because it was "on" 4 last time
Hopefully that helps explain it a little? If not, leave a comment. :-)
I just wanted to post a little bit more up to date answer - the fibonacci closure is more readable written using modern JavaScript
function fibonacci() {
let x = 0;
let y = 1;
let z = 0;
return function getNext() {
[z, x, y] = [x, y, x + y];
return z;
};
}
let fun = fibonacci();
for (let i = 0; i < 10; i++) {
console.log(fun());
}
var fibonacci = (function () {
var arr = [0, 1];
return function () {
var num = arr[arr.length - 1],
len = arr.length;
arr.push(arr[len - 1] + arr[len - 2]);
return num;
};
}());
//test
var i;
for (i = 0; i < 10; i++) {
console.log(fibonacci());
}
//1,1,2,3,5,8,13,21,34,55
See the description in http://sarathsaleem.github.com/JavaScriptTasks/
I did this as an answer to this question
Write a function which will return you first two times 1, then 2, then 3, then 5 and so on (Fibonacci numbers). Don’t use any global variables.
fibonacci = ([f0, f1] = [0, 1]) => () => ([f0, f1] = [f1, f0 + f1])[0];
I just wanted to give a more up to date answer written using modern JavaScript.