Learning Javascript functions, and having trouble with the problem below.
Modify this function so that if it’s called with 1 or 0 arguments, it returns null.
function divide(num1, num2) {
return num1 / num2;
}
let num1 = null;
let num2 = null;
let answer = divide(1,1)
console.log(answer);
TL;DR
Assuming we only need to apply a straight forward modification, I would avoid too much syntactical sugar and just write it this way:
function divide(num1, num2) {
if (arguments.length < 2) {
return null;
}
return num1/num2;
}
If we want to make it simple and elegant, I would write it this way (requires ES6 features):
const divide = (...args) => args.length < 2 ? null : args[0] / args[1];
Explanation
Improvement steps in vanilla JS (ES5 and before)
Using function arguments: this is simply an array like object that will magically appear inside your function, which contains the arguments you have passed to the function.
function divide(num1, num2) {
if (arguments.length < 2) {
return null;
}
return num1/num2;
}
While this is a great solution for the problem there are a downsides to it, if you wanted to switch to arrow function arguments object doesn't appear.
**Using ternary operator**you can farther more reduce the code by using the ternary ? which is best suitable for simple if statements
function divide(num1,num2) {
return arguments.length < 2 ? null : num1 / num2;
}
Improvement steps in ES6
Using spread (in this case it is actually called rest): the ... can be used to either collect items into an array known as rest, or expand an array known as spread.
function divide(...args) {
return args.length < 2 ? null : args[0] / args[1];
}
JavaScript will collect all the arguments passed to the function and put them into an array called args, I like this better since the reader can see where is args defined.
using arrow function: there are many difference between arrow and normal function, but many prefer it since it is shorter, and since we have a one-liner function why not use it.
const divide = (...args) => args.length < 2 ? null : args[0] / args[1];
On a final note all the previous solutions has a downside that we are only checking for length of arguments but not contents of arguments, lets assume that someone sent undefined into one of the first two arguments, you'll have 2 arguments but one of them is kinda missing and you'll get NaN since number of arguments is 2.
function divide(num1, num2) {
if (num1 === undefined || num2 === undefined) {
return null;
}
return num1/num2;
}
Demo
function divide1(num1, num2) {
if (arguments.length < 2) {
return null;
}
return num1/num2;
}
function divide2(num1,num2) {
return arguments.length < 2 ? null : num1 / num2;
}
function divide3(...args) {
return args.length < 2 ? null : args[0] / args[1];
}
const divide4 = (...args) => args.length < 2 ? null : args[0] / args[1];
const test = (cb) => {
console.log("-------->" + cb.name)
console.log(cb());
console.log(cb(1));
console.log(cb(1, 2));
console.log(cb(1, undefined));
console.log(cb(1, null));
console.log(cb(1, 2, 3));
};
test(divide1);
test(divide2);
test(divide3);
test(divide4);
Peep this.
function divide(num1, num2) {
if(arguments.length < 2) return null;
return num1 / num2;
}
The arguments object is available in all (non-arrow) function and represents all the arguments passed into the function. It has a length property that tells you how many arguments there are.
Technically passing in null would be calling it with two arguments so your example doesn't exactly represent that anyway. If you want an answer that's safe for arrow functions as well (they don't have the arguments object) you could just check to see if the second argument is a number. This would catch a lot of it.
function divide(num1, num2) {
if (typeof num2 !== 'number') return null;
return num1 / num2;
}
If you wanted to handle the edge case that the first passed argument was undefined you could check both arguments.
function divide(num1, num2) {
if (typeof num1 !== 'number' || typeof num2 !== 'number') return null;
return num1 / num2;
}
If you want to get fancy it could be a one line arrow:
const divide = (num1, num2) => typeof num2 !== 'number' ? null : num1 / num 2;
Related
This question already has answers here:
Return value from recurring function
(2 answers)
Closed 3 years ago.
I've managed to create a script that has to count the LCF (Largest Common Factor ). My task was to create the script for exact this algorithm, so, I couldn't choose another one. But I always get undefined on return. What am I doing wrong?
I've checked the whole function with the console.log and it works right. It founds the right LCF, comes to if statement where it should return the variable value and this value even the number.
I've checked the value of this variable, I've checked the type of this var, everything should be ok, but it doesn't work.
const checking = (num1, num2, t) => {
if (num1 % t === 0) {
if (num2 % t === 0) {
return t;
} else {
checking(num1, num2, t - 1);
}
} else {
checking(num1, num2, t - 1);
}
}
const bruteforce = (num1, num2) => {
//Checking if numbers are equal
if (num1 === num2) return num1;
//If no, defining minimal one
let t = 0;
num1 > num2 ? t = num2 : t = num1;
let answer = checking(num1, num2, t);
}
I expect the output of var t value, but the actual output is always undefined
When using a recursive function you should always return the call so the answer can travel up the stack:
const checking = (num1, num2, t) => {
if (num1 % t === 0) {
if (num2 % t === 0) {
return t;
} else {
return checking(num1, num2, t - 1);
}
} else {
return checking(num1, num2, t - 1);
}
}
When you recursive function recurses, it doesn't return anything. It just calls itself:
checking(num1, num2, t - 1);
But does nothing with the result of that call. Return that result:
return checking(num1, num2, t - 1);
Instructions: Write a function called "modulo". Given 2 numbers, "modulo" returns the remainder after dividing num1 by num2.
This is my code so far. When I run it on repl.it it gives the correct remainder, but when I submit the program it goes into an infinite loop and I have no clue why. I figure the return functions in the for loop would just automatically exit it. Any help would be appreciated, thanks. Basically I'm adding number2 constantly until it either hits number 1 or goes higher than it. If it goes higher, I subtract number 2 once, and find the difference.
function modulo(num1, num2) {
if(num1 === 0) {
return 0;
}
if(num2 === 0) {
return NaN;
}
if(isNaN(num1) === true || isNaN(num2) === true) {
return NaN;
}
var i = 0;
for( i = 0; i <= num1;) {
i += num2;
if(i === num1) {
return 0;
}
else if(i > num1) {
i = i - num2;
console.log(i, num1);
return num1 - i;
}
}
}
var output = modulo(25, 4);
console.log(output);
function modulo(num1, num2) { var div = num1/num2;
var remainder = div - Math.floor(div); // gives the decimal point value left out from the division
return Math.round(remainder * num2); // multiplies the remainder with num2 and gives a whole number value
}
This is pretty simpler and should work all times
I'm not entirely sure where the infinite loop is showing up; I've plugged your code into console and I can call the function just fine. What site are you using to validate?
Also, without altering too much of your exercise, I'd like to point out a couple of tiny areas where you can consolidate your code to improve readability:
if(num2 === 0) {
return NaN;
}
if(isNaN(num1) === true || isNaN(num2) === true) {
return NaN;
}
can be distilled down into
if (num2 === 0 || isNaN(num1) || isNaN(num2)) {
return NaN;
}
because in JavaScript, booleans work in such a way that everything with a real value is considered to be true, i.e. isNaN(num1) and isNaN(num2) are "true" by default.
Also, remember that you can use all your assignment operators; it's completely optional, but since you used one (i += num2;), I figured I'd point out that you could use another further down the code (i -= num2;).
Happy coding! :)
It could be another option:
function modulo(num1, num2) {
if(isNaN(num1) || isNaN(num2) ) {
return NaN;
}
var strResult = (num1/num2).toString();
var decimalPart =
parseFloat(strResult.substr(strResult.indexOf(".")));
var remainder = Math.round(decimalPart*num2);
return remainder;
}
console.log(modulo(77,9), (77%9)); // 5
console.log(modulo(549,123), (549%123)); // 57
console.log(modulo(33,6), (33%6)); // 3
I faced this question in one interview. I did not get how to solve this.
Question: Write a sum function which will add 2 numbers, but numbers can be passed to a function in following ways:
sum(3)(4) // answer should be 7
sum(3)()(4)//answer should be 7
sum(3)()()()()(4) //answer should b 7
I can solve first function using closure, in fact for the second function also I can check the arguments and if arguments length is zero I can again make a call to sum to except next parameter.
But how to make it generic ? Means even your first parameter and last parameter has 'N' number of calls & those can be empty or parameterized, it should return sum.
Recorded a video how to solve it:
https://youtu.be/7hnYMIOVEg0
Text answer:
function sum(numberOne) {
return function innerSum(numberTwo) {
if (typeof(numberTwo) === 'number') {
return numberOne + numberTwo;
}
return innerSum;
}
}
Output:
sum(3)(4); => 7
sum(5)()()(10); => 15
Basically, you need to return inner function (innerSum) up until you receive a value - then you return number.
You could also choose another name - like _sum(), or addToFirstNumber() for your method.
You can always return a function from within a function:
let a;
function sum(value) {
if (typeof value !== "number") {
return sum;
}
if (typeof a !== "number") {
a = value;
return sum;
}
let result = a + value;
a = null;
return result;
}
see https://jsfiddle.net/d9tLh11k/1/
function sum(num1) {
return function sum2(num2) {
if(num2 === undefined) {
return sum2;
}
return num1 + num2;
}
}
console.log(sum(4)()()()(3)); // -> 7
Or in ES6:
const add = num1 => num2 => num2 === undefined ? add(num1) : num1 + num2;
console.log(add(4)()()()()()(3)); // -> 7
function add (n) {
var func = function (x) {
if(typeof x==="undefined"){
x=0;
}
return add (n + x);
};
func.valueOf = func.toString = function () {
return n;
};
return func;
}
console.log(+add(1)(2)(3)()()(6));
I have already given answer of this question Here
but according to your question I have modified that
function add (n) {
var func = function (x) {
if(typeof x==="undefined"){
x=0;
}
return add (n + x);
};
func.valueOf = func.toString = function () {
return n;
};
return func;
}
console.log(+add(1)(2)(3)()()(6));
Run code like that
console.log(+add(1)(2)(3)()()(6));
This should do it
function sum(num1) {
if (arguments.length === 0){
return sum;
}
return function innerSum(num2) {
if (arguments.length > 0){
return num1 + num2;
}else{
return innerSum;
}
}
}
You can do this in a number of ways, but mostly you'll want named recursion. That is, you can have something like:
sum = start => (...args) => args.length? args[0] + start : sum(start)
but it might look cleaner to write this as:
function sum(start) {
function out(...args) {
return args.length? start + args[0] : out
}
return out;
}
I've written a version of Y that automatically caches old values in a closure using memoization.
var Y = function (f, cache) {
cache = cache || {};
return function (x) {
if (x in cache) return cache[x];
var result = f(function (n) {
return Y(f, cache)(n);
})(x);
return cache[x] = result;
};
};
Now, when almostFibonacci (defined below) is passed into the above function, it returns the value of a large Fibonacci number comfortably.
var almostFibonacci = function (f) {
return function (n) {
return n === '0' || n === '1' ? n : f(n - 1) + f(n - 2);
};
};
However, after a certain value (Number.MAX_SAFE_INTEGER), integers in JavaScript (owing to their IEEE-754 double precision format) are not accurate. So, considering the fact that the only mathematical operations in the Fibonacci function above are addition and subtraction and since operators cannot be overloaded in JavaScript, I wrote naïve implementations of the sum and difference functions (that both use strings to support big integers) which are as follows.
String.prototype.reverse = function () {
return this.split('').reverse().join('');
};
var difference = function (first, second) {
first = first.reverse();
second = second.reverse();
var firstDigit,
secondDigit,
differenceDigits = [],
differenceDigit,
carry = 0,
index = 0;
while (index < first.length || index < second.length || carry !== 0) {
firstDigit = index < first.length ? parseInt(first[index], 10) : 0;
secondDigit = index < second.length ? parseInt(second[index], 10) : 0;
differenceDigit = firstDigit - secondDigit - carry;
differenceDigits.push((differenceDigit + (differenceDigit < 0 ? 10 : 0)).toString());
carry = differenceDigit < 0 ? 1 : 0;
index++;
}
differenceDigits.reverse();
while (differenceDigits[0] === '0') differenceDigits.shift();
return differenceDigits.join('');
};
var sum = function (first, second) {
first = first.reverse();
second = second.reverse();
var firstDigit,
secondDigit,
sumDigits = [],
sumDigit,
carry = 0,
index = 0;
while (index < first.length || index < second.length || carry !== 0) {
firstDigit = index < first.length ? parseInt(first[index], 10) : 0;
secondDigit = index < second.length ? parseInt(second[index], 10) : 0;
sumDigit = firstDigit + secondDigit + carry;
sumDigits.push((sumDigit % 10).toString());
carry = sumDigit > 9 ? 1 : 0;
index++;
}
sumDigits.reverse();
while (sumDigits[0] === '0') sumDigits.shift();
return sumDigits.join('');
};
Now, by themselves, both these functions work perfectly.1
I have now updated the almostFibonacci function to as follows to use the sum function instead of + and the difference function instead of the - operator.
var almostFibonacci = function (f) {
return function (n) {
return n === '0' || n === '1' ? n : sum(f(difference(n, '1')), f(difference(n, '2')));
};
};
As you may have guessed, this does work. It crashes the fiddle in case of even a small number like 10.
Question: What could be wrong? All the functions here work perfectly individually. But in tandem, they seem to fail. Can anyone here help me debug this particularly complex scenario?
1Except an edge case for the difference function. It requires the first argument to be larger than the second.
Now, by themselves, both these functions work perfectly - Except an edge case for the difference function. It requires the first argument to be larger than the second.
And that's the problem. In your fibonacci algorithm you're at some point calculating difference("2", "2"), which needs to yield "0" to work. It does however return the empty string "", which is not tested against as your guard condition for the recursion. When in the next step computing difference("", "1"), the function will fall into an infinite loop.
Solutions:
Fix that edge case (you still won't need to cope with negative numbers)
Don't use strings for the ordinal number, but only for the fibonacci number itself. You hardly will try the compute the (253+1)th fibonacci number, will you? I would assume this to be a significant speed improvement as well.
var fibonacci = Y(function(fib) {
return function(n) {
if (n == 0) return "0";
if (n == 1) return "1";
return sum(fib(n-1), fib(n-2));
};
});
Here is how I solved the problem at hand.
Changes:
I removed the while (differenceDigits[0] === '0') differenceDigits.shift(); statement. Even though this outputs differences without truncated leading zeros, it outputs a '0' in case of an edge case like difference('2', '2').
I edited the return statement in the almostFibonacci function to return n == 0 || n == 1 ? n : sum(f(difference(n, '1')), f(difference(n, '2')));. Notice that I'm checking for 0 and not '0' with a non strict equality operator.1
1The reason I'm doing n == 0 as opposed to n === '0' is because in JavaScript, '00000' == 0 but '00000' !== '0' and in my new updated difference function, without truncated leading zeros, I can't guarantee the number of zeros for a zero output. Well, actually I can. There would be as many zeros as the length of n.
100th Fibonacci - JSFiddle
I decided to create simple isEven and isOdd function with a very simple algorithm:
function isEven(n) {
n = Number(n);
return n === 0 || !!(n && !(n%2));
}
function isOdd(n) {
return isEven(Number(n) + 1);
}
That is OK if n is with certain parameters, but fails for many scenarios. So I set out to create robust functions that deliver correct results for as many scenarios as I could, so that only integers within the limits of javascript numbers are tested, everything else returns false (including + and - infinity). Note that zero is even.
// Returns true if:
//
// n is an integer that is evenly divisible by 2
//
// Zero (+/-0) is even
// Returns false if n is not an integer, not even or NaN
// Guard against empty string
(function (global) {
function basicTests(n) {
// Deal with empty string
if (n === '')
return false;
// Convert n to Number (may set to NaN)
n = Number(n);
// Deal with NaN
if (isNaN(n))
return false;
// Deal with infinity -
if (n === Number.NEGATIVE_INFINITY || n === Number.POSITIVE_INFINITY)
return false;
// Return n as a number
return n;
}
function isEven(n) {
// Do basic tests
if (basicTests(n) === false)
return false;
// Convert to Number and proceed
n = Number(n);
// Return true/false
return n === 0 || !!(n && !(n%2));
}
global.isEven = isEven;
// Returns true if n is an integer and (n+1) is even
// Returns false if n is not an integer or (n+1) is not even
// Empty string evaluates to zero so returns false (zero is even)
function isOdd(n) {
// Do basic tests
if (basicTests(n) === false)
return false;
// Return true/false
return n === 0 || !!(n && (n%2));
}
global.isOdd = isOdd;
}(this));
Can anyone see any issues with the above? Is there a better (i.e. more accurate, faster or more concise without being obfuscated) version?
There are various posts relating to other languages, but I can't seem to find a definitive version for ECMAScript.
Use modulus:
function isEven(n) {
return n % 2 == 0;
}
function isOdd(n) {
return Math.abs(n % 2) == 1;
}
You can check that any value in Javascript can be coerced to a number with:
Number.isFinite(parseFloat(n))
This check should preferably be done outside the isEven and isOdd functions, so you don't have to duplicate error handling in both functions.
I prefer using a bit test:
if(i & 1)
{
// ODD
}
else
{
// EVEN
}
This tests whether the first bit is on which signifies an odd number.
How about the following? I only tested this in IE, but it was quite happy to handle strings representing numbers of any length, actual numbers that were integers or floats, and both functions returned false when passed a boolean, undefined, null, an array or an object. (Up to you whether you want to ignore leading or trailing blanks when a string is passed in - I've assumed they are not ignored and cause both functions to return false.)
function isEven(n) {
return /^-?\d*[02468]$/.test(n);
}
function isOdd(n) {
return /^-?\d*[13579]$/.test(n);
}
Note: there are also negative numbers.
function isOddInteger(n)
{
return isInteger(n) && (n % 2 !== 0);
}
where
function isInteger(n)
{
return n === parseInt(n, 10);
}
Why not just do this:
function oddOrEven(num){
if(num % 2 == 0)
return "even";
return "odd";
}
oddOrEven(num);
To complete Robert Brisita's bit test .
if ( ~i & 1 ) {
// Even
}
var isOdd = x => Boolean(x % 2);
var isEven = x => !isOdd(x);
var isEven = function(number) {
// Your code goes here!
if (number % 2 == 0){
return(true);
}
else{
return(false);
}
};
A few
x % 2 == 0; // Check if even
!(x & 1); // bitmask the value with 1 then invert.
((x >> 1) << 1) == x; // divide value by 2 then multiply again and check against original value
~x&1; // flip the bits and bitmask
We just need one line of code for this!
Here a newer and alternative way to do this, using the new ES6 syntax for JS functions, and the one-line syntax for the if-else statement call:
const isEven = num => ((num % 2) == 0);
alert(isEven(8)); //true
alert(isEven(9)); //false
alert(isEven(-8)); //true
A simple modification/improvement of Steve Mayne answer!
function isEvenOrOdd(n){
if(n === parseFloat(n)){
return isNumber(n) && (n % 2 == 0);
}
return false;
}
Note: Returns false if invalid!
Different way:
var isEven = function(number) {
// Your code goes here!
if (((number/2) - Math.floor(number/2)) === 0) {return true;} else {return false;};
};
isEven(69)
Otherway using strings because why not
function isEven(__num){
return String(__num/2).indexOf('.') === -1;
}
if (testNum == 0);
else if (testNum % 2 == 0);
else if ((testNum % 2) != 0 );
Maybe this?
if(ourNumber % 2 !== 0)
var num = someNumber
isEven;
parseInt(num/2) === num/2 ? isEven = true : isEven = false;
for(var a=0; a<=20;a++){
if(a%2!==0){
console.log("Odd number "+a);
}
}
for(var b=0; b<=20;a++){
if(b%2===0){
console.log("Even number "+b);
}
}
Check if number is even in a line of code:
var iseven=(_)=>_%2==0
This one is more simple!
var num = 3 //instead get your value here
var aa = ["Even", "Odd"];
alert(aa[num % 2]);
To test whether or not you have a odd or even number, this also works.
const comapare = x => integer(checkNumber(x));
function checkNumber (x) {
if (x % 2 == 0) {
return true;
}
else if (x % 2 != 0) {
return false;
}
}
function integer (x) {
if (x) {
console.log('even');
}
else {
console.log('odd');
}
}
Using modern javascript style:
const NUMBERS = "nul one two three four five six seven ocho nueve".split(" ")
const isOdd = n=> NUMBERS[n % 10].indexOf("e")!=-1
const isEven = n=> isOdd(+n+1)
function isEven(n) {return parseInt(n)%2===0?true:parseInt(n)===0?true:false}
when 0/even wanted but
isEven(0) //true
isEven(1) //false
isEven(2) //true
isEven(142856) //true
isEven(142856.142857)//true
isEven(142857.1457)//false
if (i % 2) {
return odd numbers
}
if (i % 2 - 1) {
return even numbers
}