Remove Falsy values from array solved but not understood - javascript

I just solved this challenge on freecodecamp
Remove all falsy values from an array. Return a new array; do not mutate the original array.
Falsy values in JavaScript are false, null, 0, "", undefined, and NaN.
Hint: Try converting each value to a Boolean.
i solved mine this way:
function bouncer(arr) {
return arr.filter(function(ele){return ele});
}
as opposed to this solved by freecodecamp:
function bouncer(arr) {
var check = arr.filter(function(i) {
return Boolean(i);
});
return check;
}
I can't understand why mine works correctly when called with bouncer([7, "ate", "", false, 9]);, since i'm just returning the variable in the test function without doing the boolean conversion.

JavaScript has the concept of Truthy and Falsy values.
Using Array.filter(Boolean) or Array.filter(ele => ele) is pretty much the same. Boolean will cast your value to a boolean value which can only be true or false. If you return just the value, it gets evaluated either as truthy or falsy.
If you would like to write it in a very explicit way you could do the following:
Array.filter(ele => {
return ele !=== undefined || ele !== null || ele !== false || ele !== '' || ele !== 0 || ele !== NaN
})

Related

shortcut to check if variable is null || undefined||empty string||false

I am looking for check, if my variable is one of : null || undefined || empty string || false
Right now its look messy and long:
const userHasPhoneNumber = user.phone === undefined ||
user.phone === "" ||
user.phone === false ||
user.phone === null ? false : true;
Is there shortcut?
You can shortcut x === undefined || x === null to x == null. For the others, there is no shortcut as there are some falsy number values as well. You could however do
const userHasPhoneNumber = typeof user.phone == "number" || !!user.phone
If you coerce that string to a boolean then it should check all your conditions, which is pretty much checking if user.phone is truthy.
It depends how you want to use it. If you wanted to use it in a condition, i.e. if(userHasPhoneNumber) ... then you can use the string directly : if(user.phone) as it will coerce to a boolean.
If you really need to have a boolean variable then need to cast it to a boolean explicitely:
Either through
const userHasPhoneNumber = Boolean(user.phone);
or
const userHasPhoneNumber = !!user.phone;
Note, as #Bergi commented, that there are more values that are coerced to a false value (falsy values), for example NaN or the number 0 (the string "0" will coerce to true), so it depends what your input is. If it's never a number but either a string/boolean/null/undefined, it should be fine. Here is the list of all falsy values for reference : https://developer.mozilla.org/en-US/docs/Glossary/Falsy
Use JavaScript's !!, witch will become false for null, "", undefined and false:
const user = {
phone_1: null,
phone_2: "",
phone_3: undefined,
phone_4: false
};
console.log(!!user.phone_1); // false
console.log(!!user.phone_2); // false
console.log(!!user.phone_3); // false
console.log(!!user.phone_4); // false
Note Use this with caution as some results may be different then expected, this answer shows a complete list.

What is Simpler Way to Write Code That Sums Up Length of Strings including nulls and undefineds in JavaScript

I want to add some defensive coding to the following check. I have 3 strings and I want to know if any of them have anything in them (for my purposes, null or undefined means they do not have anything in them).
if (twitterUrl.length + facebookUrl.length + linkedInUrl.length > 0) {
This works, but feels like very bulky. I use TypeScript and not sure if there is anything there that can help me with this.
if ((twitterUrl ? twitterUrl.length : 0) +
(facebookUrl ? facebookUrl.length : 0) +
(linkedInUrl ? linkedInUrl.length : 0) > 0) {
You can use the fact that empty strings are falsy¹. If you know they'll be strings or null or undefined and you don't need to worry about strings with just whitespace in them (" " is truthy¹), then:
if (twitterUrl || facebookUrl || linkedInUrl) {
If you need to worry about trimming, then a helper function is probably in order:
function present(s) {
return s && (typeof s !== "string" || s.trim());
}
and
if (present(twitterUrl) || present(facebookUrl) || present(linkedInUrl)) {
or
if ([twitterUrl, facebookUrl, linkedInUrl].some(present)) {
¹ falsy and truthy: When you use a value in a condition (like an if), JavaScript will implicitly coerce the value to a boolean. A value that coerces to false is falsy; one that coerces to true is truthy. The falsy values are "", null, undefined, 0, NaN, and of course, false. All other values (including " ") are truthy.
You could define a function as the following one:
function getLength(s){
if(typeof s !== "string") return 0;
return s.length;
}
and then use it like below:
if (getLength(twitterUrl) > 0 || getLenght(facebookUrr) > 0 || getLength(linkedInUrl){
// code
}
Essentially, getLength check if the value you pass when you call the function is a string and if so it returns its length. Otherwise, it returns 0. So in order to achieve that you want, (I want to know if any of them have anything in them), you have to check one by one the strings you have, if the first string has a length greater than zero, there isn't any need to continue the check for the other two strings. Otherwise you call the function on the second string and so on and so forth.
Try like this, normal if statement also works
const socialLinks = [twitterUrl, facebookUrl, linkedInUrl];
const hasSomething = socialLinks.some(social => social);
Here is falsy value like null, undefined, '' and etc., https://developer.mozilla.org/en-US/docs/Glossary/Falsy
if social are empty string('') or null or undefined then it's return false. We omitted return keyword because arrow function has implicit return behaviour.
This is a solution using some(), which checks whether at least one element in the array passes the test implemented by the provided function.
var twitterUrl, facebookUrl, linkedInUrl;
linkedInUrl = 'nonEmpty';
result = [twitterUrl, facebookUrl, linkedInUrl].some(arrVal => arrVal);
console.log(result);

Am I using filter right? I don't know why this solution works

I'm going through FCC basic algorithms right now, and while I passed the exercise, I'm not fully understanding why it works, as when I change things to how I think they should be it doesn't work, but when I change things so they look wrong to me it still works.
For instance, I change true to false, and it still works, or I just type true, and it still works, or I just say return value, and it works. Does filter automatically remove falsy values?
Here is my code. My original code that didn't work said if (value === true).
function bouncer(arr) {
let x = arr.filter(value => {
if (value !== true)
return value;
})
console.log(x);
return x;
}
bouncer([7, "ate", "", false, 9]);
Remove all falsy values from an array.
Falsy values in JavaScript are false, null, 0, "", undefined, and NaN.
UPDATE
Thanks for all the answers, they were all super helpful in clearing up my confusion.
function bouncer(arr) {
let x = arr.filter(ages => {
return ages;
})
return(x);
}
bouncer([7, "ate", "", false, 9]);
This is the solution I ended up re-writing, and now understand why I did what I did.
Your callback,
if (value !== true)
return value;
is equivalent to just
return value;
in your case because none of the elements in your array are true, so value !== true always holds.
If you change it to
if (value !== false)
return value;
it still executes return value; for most array elements. The only exception is false, for which your function returns undefined (because no explicit return statement is executed). undefined is falsy, so it is treated the same as return false by filter (because filter only cares whether the callback returned a true or falsy value). So in the end not returning a value if the element is false is the same as return value.
On the other hand, if you change it to
if (value === true)
return value;
then your callback would return true if the current element is true and return undefined for any other value. The net effect is removing all elements that are not true (which in your case is all elements because your input array does not contain true).
If you want to remove falsy values, you can simply say
arr.filter(value => { return value; })
// or:
arr.filter(value => value)
because you're using the value itself as the condition: Anything that looks falsy is removed by filter; anything that looks true is kept.
If you find this confusing, perhaps looking at this custom (and simplified) filter implementation clears things up:
function my_filter(arr, fn) {
var results = [];
for (var i = 0; i < arr.length; i++) {
if (fn(arr[i])) {
results.push(arr[i]);
}
}
return results;
}
// Usage would be something like:
console.log(my_filter([7, "ate", "", false, 9], value => value));
If your purpose is to return an array that only retains the truthy values, then do this:
.filter(Boolean)
In your callback to filter you don't always return a value, and if you don't, that means the corresponding value will not be retained. Furthermore, with operators like !== and === you are doing a strict comparison. So value === true will only match true, not any other truthy value. Similarly, value !== true will still match some truthy values (that are not true).
filter iterates over your array. In each element iteration the callback is called.
If you return a "truthy" value in the callback that element is kept in the resulting Array, otherwise it's not.
Your confusion stems from the fact that you think you need to return the value argument in some way. You don't.
Look at this example:
var animals = ['dog', 'dog', 'cat', 'cat']
var cats = animals.filter(value => {
if (value === 'cat') {
return true
} else {
return false
}
})
console.log(cats)
Of course the above can be simplified to this:
var animals = ['dog', 'dog', 'cat', 'cat']
var cats = animals.filter(value => {
return value === 'cat'
})
console.log(cats)
That's just it.

Comparing to multiple values using |

var newArr = arr.filter(function(val){
return val != false|null|0|""|undefined|NaN;})
I'm trying to filter our values that equal false, null, 0, "", undefined, NaN.
The code above seems to work for false, 0, and "" and I'm not sure if I'm writing null, undefined and NaN incorrectly or if the code is not supposed to work at all.
Please let me know if this is just wishful thinking
You should be able to achieve that by just returning the value itself (if you double "negate" you get a boolean)
var newArr = arr.filter(function(val){ return !!val })
That's possible because all of those values are "considered false" in javascript
If you want to clearly show all the options, then the easiest way is to use an && (AND) operator.
val !== false && val !== null && val !== 0
and so on... (or as mentioned by Jeremy Banks, use an Array together with indexOf)

JavaScript check if value is only undefined, null or false

Other than creating a function, is there a shorter way to check if a value is undefined,null or false only in JavaScript?
The below if statement is equivalent to if(val===null && val===undefined val===false)
The code works fine, I'm looking for a shorter equivalent.
if(val==null || val===false){
;
}
Above val==null evaluates to true both when val=undefined or val=null.
I was thinking maybe using bitwise operators, or some other trickery.
Well, you can always "give up" :)
function b(val){
return (val==null || val===false);
}
The best way to do it I think is:
if(val != true){
//do something
}
This will be true if val is false, NaN, or undefined.
I think what you're looking for is !!val==false which can be turned to !val (even shorter):
You see:
function checkValue(value) {
console.log(!!value);
}
checkValue(); // false
checkValue(null); // false
checkValue(undefined); // false
checkValue(false); // false
checkValue(""); // false
checkValue(true); // true
checkValue({}); // true
checkValue("any string"); // true
That works by flipping the value by using the ! operator.
If you flip null once for example like so :
console.log(!null) // that would output --> true
If you flip it twice like so :
console.log(!!null) // that would output --> false
Same with undefined or false.
Your code:
if(val==null || val===false){
;
}
would then become:
if(!val) {
;
}
That would work for all cases even when there's a string but it's length is zero.
Now if you want it to also work for the number 0 (which would become false if it was double flipped) then your if would become:
if(!val && val !== 0) {
// code runs only when val == null, undefined, false, or empty string ""
}
One way to do it is like that:
var acceptable = {"undefined": 1, "boolean": 1, "object": 1};
if(!val && acceptable[typeof val]){
// ...
}
I think it minimizes the number of operations given your restrictions making the check fast.
Another solution:
Based on the document, Boolean object will return true if the value is not 0, undefined, null, etc. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false.
So
if(Boolean(val))
{
//executable...
}
only shortcut for something like this that I know of is
var val;
(val==null || val===false) ? false: true;
Boolean(val) === false. This worked for me to check if value was falsely.
Using ? is much cleaner.
var ? function_if_exists() : function_if_doesnt_exist();
Try like Below
var Boolify = require('node-boolify').Boolify;
if (!Boolify(val)) {
//your instruction
}
Refer node-boolify

Categories

Resources