Please explain this one line of code!

Please explain this one line of code!
0.0 0

#1

Can anyone help me with this code explaining how is it working?

function bouncer(arr) {
  return arr.filter(x=>x);
  return arr;
}

#2

If x is true or truthy then filter will place it in the resultant array


#3

filter takes a function as an argument, and that function needs to return true or false.

It runs that function for every element on an array, and produces a new array. For every element, if the function returns true, it adds that element to the new array. If it returns false it doesn’t.

The kinda tricky thing filter also does is it forces (coerces) the return value of the function to be true or false.

With this challenge, all the values you need to exclude are considered “falsey” by JS, in that they coerce to false. So if, in the function, you just return the same value (function identity(x) { return x; }, or here, simply x => x) filter will see that return value as false and exclude it for the array it produces.

This is a perfectly workable way of solving the problems, but it does need internal knowledge of how JS works, and is arguably not very clear Vs other solutions


#4

@alhazen1 Whats truthy?

thanks dan :slight_smile:


#5

If you coerce a value (any value) to a Boolean in JS (explicitly, by using the Boolean function, or implicitly via if or just by using a comparison operator or whatever):

truthy is a value that coerces to true
falsey is a value that coerces to false

It is one of JavaScript’s wierdnesses (like [] > 7 makes no sense, but JS will happily try to do a comparison). It makes some things easier than in other languages but is also a common cause of difficult-to-track-down bugs


#6

I think @DanCouper did a great job of explaining truthy and filter so I won’t complicate by adding to either of those.

Sometimes it helps to demonstrate a function in less complex terms so I have re-written the function in simpler javascript. The first uses no ES6 and no array methods. All three do the same thing though.

I don’t know where you are in your studies so if this is oversimplification just skip it.

let truthies = [true, , 1, , 'a'];
let falsies = [false, null, undefined, 0, ''];

// *using for...loop and push*******
// if the statement evaluates to 'true' then
// it gets included in resultant array
function bouncer(arr) {
	const results = [];
	for (let i = 0; i < arr.length; i++) {
		if (arr[i]) results.push(arr[i]); // if truthy, then push
	}
	return results;
}

console.log(bouncer(truthies)); //[ true, 1, 'a' ]
console.log(bouncer(falsies)); //[]


// *using filter w/anonymous function******
function bouncer2(arr) {
	return arr.filter(function(x) {
		return x;  // if truthy, include in new array
	});
}

// *using filter w/arrow function****
function bouncer3(arr) {
	return arr.filter(x => x);
}

console.log(bouncer3(truthies)); //[ true, 1, 'a' ]
console.log(bouncer3(falsies)); //[]


#7

Was thinking about this, and just as an example of how coding like in the original example can cause problems:

So say you have a chunk of data which is list of numbers. Say a load of stuff pulled out of a database. If the datum is there, there’s a number, but sometimes the value of that datum is just null; nothing was saved for that entry. And you don’t care about those bills, you just want the actual data. Soooo, you get the data and you get an array like

const myData = [1, 2 ,4, 0, null, 5, 3, 0, 6, 0, 3, 1, null, 3, 7, 4, null, 0, ...]

And you can just filter it, easy, and it’s dead simple and looks really neat:

myData.filter(datum => datum);

Except that now, your filtered data looks like:

[1, 2 ,4, 5, 3, 6, 3, 1, 3, 7, 4, ...]

Even though 0 is valid, the filter is just going to strip all those 0s out, because it treats them as falsely values.

So umm, just be careful, explicit is normally better than cleverness based on JS coercion rules.