How do two ternary operators work together in JS? - javascript

So I was doing a code problem online and one of the solutions showed the following
function electionsWinners(votes, k) {
var max=Math.max(...votes)
var r=votes.filter(x=>x+k>max||x===max).length
return k?r:r==1?1:0
}
I don't think the specifics of the problem are relevant, I'm more interested in how the return statement works. I don't understand at all what gets returned, it seems that 2 ternary operators are being used but I'm not sure, can anyone help me understand how exactly this return statement functions?

Yes 2 ternary operators
return k?r:r==1?1:0
i will put the code with complete IF
if(k) //not is null
return r;
else
{
if(r==1)
return 1;
else
return 0;
}

If you convert it to if else statement then you'll better understand what's going on:
if (k) {
return r;
} else if (r === 1) {
return 1;
} else {
return 0;
}
Or
if (k) {
return r;
}
if (r === 1) {
return 1;
}
return 0;

You can look at
k?r:r==1?1:0
as a single expression. Each ? is connected to its immediately following :, so it's equivalent to:
k ? r : (r==1 ? 1 : 0)
where the second conditional operator takes effect only if the k is falsey. In that second conditional, if r is 1, 1 is returned, else 0 is returned.
Might be clearer with indentation:
return (k
? r
: (r == 1
? 1
: 0
)
);

The first test is k ? is k not 0/undefined/null? If so, return r (r) else : if r is 1 (r==1 ?) return 1 (1) otherwise return 0 (0))

Related

How to return NaN

I'm working on a codewars problem-here's the question:
-Write a function that accepts two integers and returns the remainder of dividing the larger value by the smaller value.
-Division by zero should return NaN.
I have the first part figured out, but how do I return NaN if I divide by 0? I don't know a lot about NaN and I'm pretty new to JavaScript.
function remainder(n, m){
if (n > m) {
let answer = n % m;
if (m === 0) {
return undefined;
}
else {
return answer;
}
}
else if (m > n) {
let answer = m % n;
if (n === 0) {
return undefined;
}
else {
return answer;
}
}
else {
let answer = n % m;
return answer;
}
}
Edit: solved, answer is below
Welcome to our community!
NaN stands for Not-a-Number and it is a property of the global object(in order to understand more about the global object, I would recommend reading about Scopes).
You could access NaN like this:
window.NaN => from a browser
Number.NaN
NaN
If you want to check if a number is NaN you could use: isNaN.
If you want to use it in a function you can just do
function test(x){
if(isNaN(x)){
return NaN;
}
return x;
}
To come back to your problem, you could do something like this:
function calculateRemainder(a,b){
return a>b ? a % b : b % a
}
Where % is known as the remainder operator about which you can read more here. This operator returns NaN if you try to divide by 0 or to operate with Infinity.
The following operations return NaN:
NaN % 2
Infinity % 0
10 % 0
Infinity % Infinity
The problem is that % is not the divider syntax, but this is /.
I created a basic example for you:
In this example, the console logs "divider is 0"
function divider(up, down) {
if (down == 0) {
console.log("divider is 0");
return NaN
} else {
console.log(up / down);
}
}
divider(5, 0);
But here, it will log 2.5
function divider(up, down) {
if (down == 0) {
console.log("divider is 0");
return NaN
} else {
console.log(up / down);
}
}
divider(5, 2);
This is my answer (with help from the comments on my question), and it worked. Thank you for your help!
function remainder(n, m){
if (n > m) {
let answer = n % m;
if (m === 0) {
return NaN;
}
else {
return answer;
}
}
else if (m > n) {
let answer = m % n;
if (n === 0) {
return NaN;
}
else {
return answer;
}
}
else {
let answer = n % m;
return answer;
}
}

Sum of Digits / Digital Root codewars kata [duplicate]

This question already has answers here:
Recursive function returns undefined
(3 answers)
Closed 1 year ago.
Please, help me. I don't understand. Why second solution returns undefined?
function digital_root(n) {
return n < 10 ? n : digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
console.log(digital_root(12345678));
// expected output: 9
function digital_root(n) {
if (n < 10) {
return n;
} else {
digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
}
console.log(digital_root(12345678));
// output: undefined
This happens because your second code ignores the value you get returned from the recursive call. You should do something with it... return it.
function digital_root(n) {
if (n < 10) {
return n;
} else {
return digital_root(n.toString().split('').map(Number).reduce((a, b) => a + b));
}
}
console.log(digital_root(12345678));
Unrelated, but you can combine split and map by doing Array.from. Also the first version joins the two return statements with the conditional operator into a return of one expression:
const digital_root = n => n < 10 ? n
: digital_root(Array.from(n.toString(), Number).reduce((a, b) => a + b));
console.log(digital_root(12345678));

Javascript: The Good Parts - Why is - 1 being used here

i am merely just curious if he is using this to iterate over the entire array. i always had a feeling this is what -1 did but i want the correct answer since assuming will get me nowhere but mistakes. Appreciate any assistance.
m.sort(function(a, b){
if(a === b) {
return 0;
}
if(typeof a === typeof b) {
return a < b ? -1 : 1;
}
return typeof a < typeof b ? -1 : 1;
});
It is being used because sort expects the callback to indicate if a was less than (-1), equal to (0) or larger than (1)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

How does a negative value turn positive by calling it negative in the console?

i used Math.abs but I fail and found this solution, I am following on eloquent javascript and how did negative value is turned to positive, here is the code:
function isEven(n) {
if (n == 0) {
return true;
}
else if (n == 1) {
return false;
}
else if (n < 0) {
console.log(-n);
return isEven(-n); // turn -3 to 3?
}
else {
return isEven(n - 2);
}
}
console.log(isEven(-3));
Here you are a simpler test case:
> console.log( -(-3) );
3
This is not a JavaScript peculiarity, it's how maths work.
Console has nothing to do with this.
Think back to your math class. -n is a shortened expression for (-1) * n. If you multiply two negative numbers, the result is a positive number - and since you're multiplying by negative 1 (where positive 1 is identity for multiplication), the result is the same number, but positive.
Since you're checking if (n < 0) before you multiply by -1, you'll always get a positive number.
However, this is almost definitely not what you want - the code you found seems to be an example of how to use recursion to solve common problems. In real-world Javascript, you'd want something more like this:
function isEven(x)
{
return (Math.abs(x) % 2) === 0;
}
it has to be recursion
Lets break the mold! Using -1 instead of 2. Assuming an integer;
function isEven(x) {
if (x === 0) return 1; // ended
return -1 * (isEven(Math.abs(x) - 1) ? 1 : -1) === 1;
}
Other fun ways to test for even that don't need 2 or mod/remaineder
function isEven(x) {
return Math.round(Math.sin(5 * x / Math.PI)) === 0;
}
An O(log n) recursion
function isEven(x, a) {
if (!a) a = [true, false];
if (a.length > x) return a[x];
return isEven(x, a.concat(a));
}

Understanding negative numbers in recursion

I'm just getting my head around recursion in javascript using the book Eloquent Javascript but don't fully understand what is happening to the negative number (-1) in this fiddle:
http://jsfiddle.net/greenhulk01/kg5ton1t/
function isEven(n) {
if (n == 0) {
return true;
} else if (n == 1) {
return false;
} else if (n < 0) {
return isEven(-n);
} else {
return isEven(n - 2);
}
};
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → false
I understand everything that is going on in this recursion except for how "return isEven(-n);" is being handled. Using console.log i can see it is returned as undefined so not sure why it is caught by the false statement.
Any pointers to help my understanding would be really appreciated.
Cheers.
isEven(-n) just takes advantage of the fact that if -n is even, n is even, too. So basically isEven(-10) calls isEven(10)
BTW: Did you try isEven(1.5)? I'd expect false, but I'd guess you'd get a stack overflow. I'd write this as
function isEven(n) {
if (n < 0) {
return isEven(-n);
}
if (n >= 2) {
return isEven(n - 2);
}
return n == 0;
};
BTW 2: Without using recursion, you could just write
function isEven(n) {
return n % 2 == 0;
}

Categories