This one stumped me for a while, and I eventually just looked at the solution online. The hint was fairly cryptic, and manipulating "De Morgan's Laws" in JS with &&, !, || is pretty complicating still. I'm starting to grasp it, but not quite there yet. I imagine I will need a fair bit of practice and time to understand these concepts thoroughly. Anyway, here is the question for one of the exercises at the end of chapter 5:
Analogous to the some method, arrays also have an every method. This one returns true when the given function returns true for every element in the array. In a way, some is a version of the || operator that acts on arrays, and every is like the && operator.
Implement every as a function that takes an array and a predicate function as parameters. Write two versions, one using a loop and one using the some method.
function every(array, test) {
// Your code here.
}
console.log(every([1, 3, 5], n => n < 10));
// → true
console.log(every([2, 4, 16], n => n < 10));
// → false
console.log(every([], n => n < 10));
// → true
I was able to get the first version using array.every; it wasn't too hard. But the solution for using the some method I still don't understand. Here's the solution to the second part of the question:
function every(array, test) {
return !array.some(element => !test(element));
}
I'm trying to work this out in my head, and thought that maybe a SO member could help me understand what's happening. Can someone talk me through this?
Thanks in advance!
Jordan
You could build a table of truth and have a look which value yields which result.
This example take the second example and shows for the first two elements an intermediate result, pretending here would stop the loop and the final result.
n < 10 !(n < 10)
value compare1 every compare2 some !some comment
--------- --------- --------- --------- --------- --------- -------------------
2 true false
4 true false
true false true intermediate result
16 false true
false true false final result
^^^^^ ^^^^^
By mentioning De Morgan's laws, a term can be expressed by changing the operator from logical AND && to logical OR || or vice versa by taking negated values and finally negate the whole expression.
a && b && c
!(!a || !b || !c)
Both expressions are equal (for boolean values).
Array#every acts like using && and Array#some like ||.
To negate some, take every and vice versa. This replacement need to negate the condition inside of the callback and a negation of the the result.
Related
This question already has answers here:
Empty arrays seem to equal true and false at the same time
(10 answers)
Closed 4 years ago.
I was trying out a code snippet and the results are different for an empty array check inside a console.log statement and in a conditional statement.
Help/Thoughts on why this is different?
Thanks in advance!
//Output: true
if([]) {
console.log(true)
} else{
console.log(false)
}
//Output: false
console.log([] == true)
You seem to be running into a known JavaScript quirk.
"[] is truthy, but not true"
The problem isn't where you are doing the evaluations, but rather that the two evaluations which seem identical are actually different.
See
https://github.com/denysdovhan/wtfjs#-is-truthy-but-not-true
My assumption is that the if/else block, in part of its "truthful" test is checking if something exists (not just if it is true or not) -- wherein the straight console print is comparing the value of the empty array against a boolean (which would be false)
let test = 'apple';
if( test ){
console.log( 'if/else: ' + true );
}else{
console.log( 'if/else: ' + false );
}
console.log( 'log: ' + ( test == true ) );
The two snippets are actually doing different things, hence the different results.
The first, with [] as the condition of the if statement, coerces the array to a Boolean value. (if, naturally enough, only works on Booleans, and JS will happily convert the given value if it isn't already Boolean.) This produces true - all objects in JS are "truthy", which includes all arrays.
For the second snippet, you are using the "loose equality" operator == - for which the JS specification provides a set of rules for how to convert the values into other types, eventually reaching a straightforward comparison between two values of the same type. You might want, or hope, that comparing a non-Boolean to true or false in this situation coerced the non-Boolean to Boolean - but this isn't what happens. What the specification says is that first the Boolean is coerced to number value - resulting in 1 for true (and 0 for false). So it reduces to [] == 1 - which will go through a few more conversions before resulting in a false result.
The key point is that no conversion to Boolean happens in the second case. If you think this is stupid, you're probably right. This is a bit of a gotcha, and one of the reasons many guides tell you never to use == in JS. I don't actually agree with that advice in general (and hate linters telling me to always use === in any circumstances) - but you do have to be aware of some dangers. And using == to compare a value to true or false is something to always avoid.
Luckily, if you want to test if x is truthy or falsy, you have a very short and understandable way to do it - the one you used in the first snippet here: if (x)
[edit] So my original answer was confusing as heck, and there are some incongruencies in the many answers you find on this subject all over the internet; so, let me try this again:
Part 1: Why they are Different
if([]) and if([] == true) are not the same operation. If you see the below example, you will get the same result when doing the same operation.
//Output: false
if([] == true) {
console.log(true);
} else{
console.log(false);
}
//Output: false
console.log([] == true);
Part 2: Why it matters AKA: the confusing bits
In JS, the following is a common expression used to see if an object/variable exists:
var foo = "Hello World";
if (foo) ...
From a design perspective, this test is not important to see if foo is equal to true or false, it is a test to see if the program can find the object or variable foo. If it finds foo, then it executes the results in the "then" condition, otherwise you get the "else" condition. So, in this case, it will convert foo to either false for does not exist, or true for does exist. So in this case the string is reduced to a boolean.
In contrast:
var foo = "Hello World";
if (foo == true) ...
Is typically trying to find out if the value of foo actually equals true. In this case, you are comparing the value of foo "Hello World" to a boolean, so in this case, "Hello World" does not equal true.
Just like foo, [] can be evaluated more than one way. An empty array is still an object; so, in the first case, it coerces to true because it wants to know if [] can be found; however, [] also equals ['']. So now picture this:
if (['bar'] == 'bar') ...
In this case, JS will not look at ['bar'] to see if it is there, but as an object containing a single value which it can convert to the string, 'bar'.
So:
if([]); // is true because it is an object test that evaluates as (1 === 1)
and
if([] == true) // is false because it is a string test that evaluates as ('' == 1) to (0 === 1)
I've been working for some time on a Javascript FP library called Ramda, and I'm having a slight problem with naming things. (You've heard the old line, right? "There are only two hard problems in Computer Science: cache invalidation, naming things, and off-by-one errors.")
In this library, (almost) every function of more than one parameter is automatically curried. And this works well for most use-cases. But there are some issues with a few functions which are non-commutative binary operators. The issue is that the English names often tend to imply something different than what happens when currying is applied. For example,
var div10 = divide(10);
sounds like it should be a function that divides its parameter by 10. But in fact it divides its parameter into 10, which is pretty clear if you look at the definition:
var divide = curry(function(a, b) {
return a / b;
});
So instead the expected:
div10(50); //=> 5 // NO!!
In fact, you get
div10(50); //=> 0.2 // Correct, but surprising!
We handle this by documenting the difference from people's possible expectations, and creating divideBy, which is just flip(divide) and subtractN, which is flip(subtract). But we haven't found a good equivalent for functions such as lt:
R.lt = curry(function(a, b) {
return a < b;
});
or its cousins lte, gt, and gte.
My own intuition would be that
map(lt(5), [8, 6, 7, 5, 3, 0, 9]);
//=> [false, false, false, false, true, true, false]
But of course, it actually returns
//=> [true, true, true, false, false, false, true]
So I'd like to do the same document-and-point-to-alternate-name routine for lt and its ilk. But I haven't been able to find a good name. The only real candidate has been ltVal and that doesn't really work when called with both arguments. We did discuss this issue, but had no good conclusions.
Have others dealt with this and come up with good solutions? Or even if not, any good suggestions for a name for the flipped versions of these functions?
Update
Someone suggested that this be closed because 'unclear what you were asking', and I guess the question really was lost a bit in the explanation. The simple question is:
What would be a good, intuitive name for a flipped version of lt?
First of all, kudos on the functional programming library that you are maintaining. I've always wanted to write one myself, but I've never found the time to do so.
Considering the fact that you are writing a functional programming library I'm going to assume that you know about Haskell. In Haskell we have functions and operators. Functions are always prefix. Operators are always infix.
Functions in Haskell can be converted into operators using backticks. For example div 6 3 can be written as 6 `div` 3. Similarly operators can be converted into functions using parentheses. For example 2 < 3 can be written as (<) 2 3.
Operators can also be partially applied using sections. There are two types of sections: left sections (e.g. (2 <) and (6 `div`)) and right sections (e.g. (< 3) and (`div` 3)). Left sections are translated as follows: (2 <) becomes (<) 2. Right sections: (< 3) becomes flip (<) 3.
In JavaScript we only have functions. There is no “good” way to create operators in JavaScript. You can write code like (2).lt(3), but in my humble opinion it is uncouth and I would strongly advise against writing code like that.
So trivially we can write normal functions and operators as functions:
div(6, 3) // normal function: div 6 3
lt(2, 3) // operator as a function: (<) 2 3
Writing and implementing infix operators in JavaScript is a pain. Hence we won't have the following:
(6).div(3) // function as an operator: 6 `div` 3
(2).lt(3) // normal operator: 2 < 3
However sections are important. Let's start with the right section:
div(3) // right section: (`div` 3)
lt(3) // right section: (< 3)
When I see div(3) I would expect it to be a right section (i.e. it should behave as (`div` 3)). Hence, according to the principle of least astonishment, this is the way it should be implemented.
Now comes the question of left sections. If div(3) is a right section then what should a left section look like? In my humble opinion it should look like this:
div(6, _) // left section: (6 `div`)
lt(2, _) // left section: (2 <)
To me this reads as “divide 6 by something” and “is 2 lesser than something?” I prefer this way because it is explicit. According to The Zen of Python, “Explicit is better than implicit.”
So how does this affect existing code? For example, consider the filter function. To filter the odd numbers in a list we would write filter(odd, list). For such a function does currying work as expected? For example, how would we write a filterOdd function?
var filterOdd = filter(odd); // expected solution
var filterOdd = filter(odd, _); // left section, astonished?
According to the principle of least astonishment it should simply be filter(odd). The filter function is not meant to be used as an operator. Hence the programmer should not be forced to use it as a left section. There should be a clear distinction between functions and “function operators”.
Fortunately distinguishing between functions and function operators is pretty intuitive. For example, the filter function is clearly not a function operator:
filter odd list -- filter the odd numbers from the list; makes sense
odd `filter` list -- odd filter of list? huh?
On the other hand the elem function is clearly a function operator:
list `elem` n -- element n of the list; makes sense
elem list n -- element list, n? huh?
It's important to note that this distinction is only possible because functions and function operators are mutually exclusive. It stands to reason that given a function it may either be a normal function or else a function operator, but not both.
It's interesting to note that given a binary function if you flip its arguments then it becomes a binary operator and vice versa. For example consider the flipped variants of filter and elem:
list `filter` odd -- now filter makes sense an an operator
elem n list -- now elem makes sense as a function
In fact this could be generalized for any n-arity function were n is greater than 1. You see, every function has a primary argument. Trivially, for unary functions this distinction is irrelevant. However for non-unary functions this distinction is important.
If the primary argument of the function comes at the end of the argument list then the function is a normal function (e.g. filter odd list where list is the primary argument). Having the primary argument at the end of the list is necessary for function composition.
If the primary argument of the function comes at the beginning of the argument list then the function is a function operator (e.g. list `elem` n where list is the primary argument).
Operators are analogous to methods in OOP and the primary argument is analogous to the object of the method. For example list `elem` n would be written as list.elem(n) in OOP. Chaining methods in OOP is analogous to function composition chains in FP[1].
The primary argument of the function may only be either at the beginning or at the end of the argument list. It wouldn't make sense for it to be anywhere else. This property is vacuously true for binary functions. Hence flipping binary functions makes them operators and vice-versa.
The rest of the arguments along with the function form an indivisible atom called the stem of the argument list. For example in filter odd list the stem is filter odd. In list `elem` n the stem is (`elem` n).
The order and the elements of the stem must remain unchanged for the expression to make sense. This is why odd `filter` list and elem list n don't make any sense. However list `filter` odd and elem n list make sense because the stem is unchanged.
Coming back to the main topic, since functions and function operators are mutually exclusive you could simply treat function operators differently than the way you treat normal functions.
We want operators to have the following behavior:
div(6, 3) // normal operator: 6 `div` 3
div(6, _) // left section: (6 `div`)
div(3) // right section: (`div` 3)
We want to define operators as follows:
var div = op(function (a, b) {
return a / b;
});
The definition of the op function is simple:
function op(f) {
var length = f.length, _; // we want underscore to be undefined
if (length < 2) throw new Error("Expected binary function.");
var left = R.curry(f), right = R.curry(R.flip(f));
return function (a, b) {
switch (arguments.length) {
case 0: throw new Error("No arguments.");
case 1: return right(a);
case 2: if (b === _) return left(a);
default: return left.apply(null, arguments);
}
};
}
The op function is similar to using backticks to convert a function into a operator in Haskell. Hence you could add it as a standard library function for Ramda. Also mention in the docs that the primary argument of an operator should be the first argument (i.e. it should look like OOP, not FP).
[1] On a side note it would be awesome if Ramda allowed you to compose functions as though it was chaining methods in regular JavaScript (e.g. foo(a, b).bar(c) instead of compose(bar(c), foo(a, b))). It's difficult, but doable.
We all know that naming in programming is serious business, particularly when it comes to functions in curried form. It is a valid solution to handle this issue with a programmatic approach as Aadit did in his response. However, I see two issues with his implementation:
it introduces function operators with left/right sections in Javascript, which are not part of the language
it requires a hideous placeholder or undefined hack to achieve that
Javascript has no curried operators and thus no left or right sections. An idiomatic Javascript solution should consider that.
The cause of the problem
Curried functions don't have a notion of arity, because every function invocation requires exactly one argument. You can either partially or completely apply curried functions without any helpers:
const add = y => x => x + y;
const add2 = add(2); // partial application
add(2)(3); // complete application
Usually the last argument of a function is its primarily one, because it is passed through function compositions (similar to objects that allow method chaining). Consequently when you partially apply a function, you want to pass its initial arguments:
const comp = f => g => x => f(g(x));
const map = f => xs => xs.map(x => f(x));
const inc = x => x + 1;
const sqr = x => x * x;
comp(map(inc)) (map(sqr)) ([1,2,3]); // [2,5,10]
Operator functions are special in this regard. They are binary functions that reduce their two arguments to a single return value. Since not every operator is commutative (a - b !== b - a) the argument order matters. For this reason operator functions don't have a primarily argument. But people are accustomed to read expressions with them in a certain way depending on the type of application:
const concat = y => xs => xs.concat(y);
const sub = y => x => x - y;
// partial application:
const concat4 = concat(4);
const sub4 = sub(4);
concat4([1,2,3]); // [1,2,3,4] - OK
sub4(3); // -1 - OK
// complete application:
concat([1,2,3]) (4); // [4,1,2,3] - ouch!
sub(4) (3); // -1 - ouch!
We defined concat and sub with flipped arguments, so that partial application works as expected. This evidently doesn't apply to complete application though.
A manual solution
const flip = f => y => x => f(x) (y);
const concat_ = flip(concat);
const sub_ = flip(sub);
concat_(xs) (4); // [1,2,3,4] - OK
sub_(4) (3); // 1 - OK
concat_ and sub_ correspond to left sections in Haskell. Please note that function operators like add or lt don't need a left section version because the former are commutative and the latter are predicates, which have logical counterparts:
const comp2 = f => g => x => y => f(g(x) (y));
const map = f => xs => xs.map(x => f(x));
const flip = f => y => x => f(x) (y);
const not = x => !x;
const notf2 = comp2(not);
const lt = y => x => x < y;
const gt = flip(lt);
const lte = notf2(gt);
const gte = notf2(lt);
map(lt(5)) ([8, 6, 7, 5, 3, 0, 9]);
// [false, false, false, false, true, true, false]
map(gte(5)) ([8, 6, 7, 5, 3, 0, 9]);
// [true, true, true, true, false, false, true]
Conclusion
We should solve this naming issue rather with a naming convention then with a programmatic solution which extends Javascript in a non-idiomatic way. Naming conventions are not ideal...well, just like Javascript.
What is the meaning of && in this JavaScript code?
function doIt(a) {
var b = a.parents(),
c = 1;
return b.each(function() {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
}
normally I would think this would be a logical operator AND, but I can't figure out what it does in this line.
The logical AND operator in this case is used in place of an IF-statement. It will set c to 0 if jQuery(this).hasClass("free-content") returns a truthy value.
It's equivalent to:
if (jQuery(this).hasClass("free-content")) {
c = 0;
}
You wondering what it means is actually the reason I dislike this type of coding and consider it a bad practice. It's hard to read and can create confusion, which in turn can create bugs.
It's also worth noting what logical AND returns, if you want to use the returned value:
(Logical AND) Returns expr1 if it can be converted to false; otherwise, returns expr2. Thus, when used with Boolean values, && returns true if both operands are true; otherwise, returns false.
Here's an example showing, in my opinion, bad code since it's hard to follow:
var foo = bar && baz || qux;
The above code is equivalent to:
var foo;
if (bar && baz) {
foo = baz;
} else {
foo = qux;
}
Summary: Do not use logical operators as a nifty way to replace IF-statements or to save keystrokes. It will most likely come back and bite you or someone else in the ass.
I know there will be people arguing against me on this (usually the same people who doesn't want to use semicolon because ASI), but it's just a really bad idea to write code that only an expert would understand. There's no argument against it.
return b.each(function () {
jQuery(this).hasClass("free-content") && (c = 0)
}), c
b.each loops over all entries in b, and checks whether the current element has the class free-content set. Only if that yields true, the second part of the expression is evaluated – because they are concatenated via &&, and JavaScript stops evaluating such an expression when the first part is false, because then the whole expression can’t become true any more.
So if there is an element with that class, the second part is evaluated – and thereby c is set to the value 0 (because that’s the assignment operator = there, and not a comparison).
And after that each loop is finished, the value of c is returned to the outside – because each() and c are connected via the comma operator , here, which evaluates its operands from left to right and then “returns” the second one.
JavaScript allows a lot of “fancy” coding like this, but as Marcus already said in his answer, that is hard to read, and there is no actual advantage here over, say
b.each(function() {
if(jQuery(this).hasClass("free-content")) {
c = 0;
return false;
}
});
return c;
I added the return false here inside the each loop, because once we found an element with that class, we don’t need to search the rest of them any more – that’s something that the person who came up with the original code forgot to do in all their “fancy-ness” … their loop will continue to iterate over all of b’s elements, not matter if it finds the element it is looking for in the first round already.
This question already exists:
What does `!!~` mean in javascript? [duplicate]
Closed 8 years ago.
I was reading this blog post which mentioned using:
!!~
I have no idea what this does? at first I thought it would give an error, but the code below does run:
var _sessions = [
"_SID_1",
"_SID_2",
"_SID_3",
"_SID_4"
];
if(!!~_sessions.indexOf("_SID_5")) {
console.log('found');
} else {
console.log('!found');
}
output:
node test.js
!found
~ is the bitwise not operator. It inverts the bits of its operand. ! is the logical not operator. The bitwise not operator will return 0 when applied to -1, which is what indexOf returns when the value is not found in the array. Since 0 evaluates to false, doubly negating it will simply return false (a boolean value, rather than a numeric one):
var index = _sessions.indexOf("_SID_5");
console.log(~index); // 0
console.log(!~index); // true
console.log(!!~index); //false
The bitwise not operator will return a value less than 0 for any other possible value returned by indexOf. Since any other value will evaluate to true, it's just a shorthand method (kind of... they are both the same number of characters!) of checking whether an element exists in an array, rather than explicitly comparing with -1:
if (_sessions.indexOf("_SID_5") > -1) {
// This would work the same way
}
Update
With regards to the performance of this, it appears (in Chrome at least) to be marginally slower than the more common comparison with -1 (which itself is marginally slower than a comparison with 0).
Here's a test case and here's the results:
Update 2
In fact, the code in your question can be shortened, which may have been what the author was attempting to do. You can simply remove the !!, since the ~ will always result in 0 or below (and 0 is the only value that will evaluate to false):
if (~_sessions.indexOf("_SID_5")) {
// This works too
}
However, in a slightly different situation it could make sense to add in the ! operators. If you were to store the result of the bitwise operator in a variable, it would be a numeric value. By applying the logical not operator, you get a boolean value (and applying it again ensures you get the correct boolean value). If for some reason you require a boolean value over a numeric one, it makes a little bit more sense (but you can still just use the normal comparison with -1 or 0):
var inArray = !!~_sessions.indexOf("_SID_5");
console.log(typeof inArray); // boolean
Donald Knuth: "[...] premature optimization is the root of all evil"
For the sake of readability: please use
.indexOf !== -1
This explains it well:
The tilde operator in Javascript
Mixing the two NOT operators together can produce some interesting results:
!~(-2) = false
!~(-1) = true
!~(0) = false
!~(1) = false
!~(2) = false
So this just checks if the value equals -1 or not, and indexOf returns -1 if it does not find a match
In javascript, when using an if statement with multiple conditions to test for, does javascript test them all regardless, or will it bail before testing them all if it's already false?
For example:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
Will javascript test for all 3 of those conditions or, after seeing that b does not equal 1, and is therefore false, will it exit the statement?
I ask from a performance standpoint. If, for instance, I'm testing 3 complex jQuery selectors I'd rather not have jQuery traverse the DOM 3 times if it's obvious via the first one that it's going to return FALSE. (In which case it'd make more sense to nest 3 if statements).
ADDENDUM: More of a curiosity, what is the proper term for this? I notice that many of you use the term 'short circuit'. Also, do some languages do this and others dont?
The && operator "short-circuits" - that is, if the left condition is false, it doesn't bother evaluating the right one.
Similarly, the || operator short-circuits if the left condition is true.
EDIT: Though, you shouldn't worry about performance until you've benchmarked and determined that it's a problem. Premature micro-optimization is the bane of maintainability.
From a performance standpoint, this is not a micro-optimization.
If we have 3 Boolean variables, a, b, c that is a micro-optimization.
If we call 3 functions that return Boolean variables, each function may take a long time, and not only is it important to know this short circuits, but in what order. For example:
if (takesSeconds() && takesMinutes())
is much better than
if (takesMinutes() && takesSeconds())
if both are equally likely to return false.
That's why you can do in javascript code like
var x = x || 2;
Which would mean that if x is undefined or otherwise 'false' then the default value is 2.
In case someone's wondering if there is a way to force the evaluation of all condition, in some cases the bitwise operators & and | can be used
var testOr = true | alert(""); //alert pops up
var testAnd = false & alert(""); //alert pops up
These should be used really carefully because bitwise operators are arithmetic operators that works on single bits of their operand and can't always function as "non short-circuit" version of && and ||
Example:
-2147483648 && 1 = 1
but
-2147483648 & 1 = 0
Hope it helps someone who arrived here looking for information like this (like me) and thanks to #Max for the correction and the counter-example
It will only test all the conditions if the first ones are true, test it for yourself:
javascript: alert (false && alert("A") && false);
It short circuits - only a and b will be compared in your example.
Another reason why stopping evaluation with 1 or more parameters to the left.
if (response.authResponse && (response.authResponse.accessToken != user.accessToken)){
...
}
the second evaluation relies on the first being true and won't throw a compile error if response.authResponse is null or undefined etc because the first condition failed.
Other languages had this problem in the early days and I think it's a standard approach in building compilers now.
It exits after seeing that b does not equal one.
For anyone on this question confused because they're not seeing the short-circuit behaviour when using an || in conjunction with an ? operator like so:
x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected
it seems like the short circuit rule isn't working. Why is it evaluating the second term of the || (true ? 2 : 3) when the first is true? It turns out to be an order of operations problem because the above is the equivalent of
x = (1 || true) ? 2 : 3
with the || evaluated first and the ? evaluated second. What you likely want is:
x = 1 || (true ? 2 : 3)
For this case:
a = 1
b = 2
c = 1
if (a==1 && b==1 && c==1)
You can use:
if ([a, b, c].every(x => x == 1))
// do something if a, b and c are equal to 1.
If you want to know if at least one is equal to 1, use the some() method instead of every():
if ([a, b, c].some(x => x == 1))
// do something if a, b or c is equal to 1.
every() and some() are array methods.