I am doing some little exercises to mantain fresh my knowledge of js quirks. I tried to write some simple filters that returns me a new array containing certain elements wheater they are string, numbers, ecc ... and I was surprised of what arr.filter(String) produces when in the given array there are also Numbers.
function onlyString(arr) {
return arr.filter(String);
}
onlyString([2, 4, "", "omg", ]) // returns [2, 4, "omg"]
Then I wanted to see what arr.filter(Number) would retrun
function onlyString(arr) {
return arr.filter(Number);
}
onlyString([2, 4, "", "omg", ]) // returns [2, 4]
Also, I added an empty object inside arr to see what would happen:
function onlyString(arr) {
return arr.filter(Object);
}
onlyString([2, 4, "", "omg", {}]) // returns [2, 4, "", "omg", {}]
At first sight, here, I was more confused but then I thought that the return array is correct because in js everything is an object, or am I right in this case?
By the way, I really want to understand what happened under the hood in the String filter, hope you can help me
The functions you are passing to .filter are not "is this an instance of" predicates, they are the actual constructors for those types.
Therefore if that constructor accepts a given value and returns a newly created "truthy" object in response it will remain in the returned list, e.g.
String("") -> "" -> falsey -> filteredNumber("") -> 0 -> falsey -> filteredNumber("omg") -> NaN -> falsey -> filteredObject("") -> String("") -> truthy -> not-filteredHere's another way to implement what you want using a generic helper function that creates a predicate function that matches the specified type.
function is(type) {
return function(o) {
return Object(o) instanceof type;
}
}
function onlyString(array) { return array.filter(is(String)) };
usage:
onlyString([2, 4, "", "omg", ])
> [ "", "omg" ]
Array.filter will filter out arr values depending on the result of function passed in it. If it's true, it will be stored in the array. If it's false, it will be removed from the array.
Now, if you check the result of String(), Number() & Object(), you will see that the values evaluating to false for example "", 0, NaN are filtered out. Others are returned in the array.
function onlyString(arr) {
return arr.filter(String);
}
console.log(String(2), String(4), String(""), String("omg"));
console.log(onlyString([2, 4, "", "omg", ]));
function onlyNumber(arr) {
return arr.filter(Number);
}
console.log(Number(2), Number(4), Number(""), Number("omg"));
console.log(onlyNumber([2, 4, "", "omg", ]));
function onlyObject(arr) {
return arr.filter(Object);
}
console.log(Object(2), Object(4), Object(""), Object("omg"));
console.log(onlyObject([2, 4, "", "omg", {}]));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With