Falsy Bouncer: does this code have the right to exist?

It passes the test ofc, but is it a good way to write functions like this?
I know that simpler solution is to use

arr.filter(Boolean);

but is there a reason to come up with something like this in the future?


function bouncer(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (!arr[i]) {
      arr.splice(i, 1);
      i--;
    }
  }

  return arr;
}

console.log(bouncer([false, null, 0, NaN, undefined, ""]));
console.log(bouncer([7, "ate", "", false, 9]));

In general, nothing wrong with writing your own filter logic instead of using the built in filter method.

In this case, your code can lead to errors.
splice change the content of the array, but since you are looping over it, you may skip some elements.

This is because the array is being re-indexed when you do a .splice() , which means your .length is obsolete.
I see that you are updating i to avoid this, but in my opinion it’s not worth using a possible “risky” method when you can use different strategies that don’t change the original array.

1 Like

Thanks for the answer :slight_smile:

So is it always better to use build-in methods?

My concern about them is perfomance issues (even though it maybe not that relevant on such a small scale), so I’ve been trying to design solutions for all exercises with basic things like loops. Am I doing it wrong? :smiley:

“Always” is a strong word. There’s no real right or wrong, better or worse. In general is a matter of tradeoffs.

for is faster that filter, but unless there’s some sort of edge case the difference is in most cases negligible.

However there’s a second cost to consider: Developer cost.
How much more expensive in terms of time and effort consumed by a developer to read, understand and maintain a code in the long term?

Just to give you an example:

const keepString = arr => arr.filter(el => typeof el === 'string');

vs

const keepString = arr => {
  let n = [];
  for(let i = 0; i < arr.length; i++) {
    if(typeof arr[i] === 'string') {
      n.push(arr[i])
    }
  }
  return n;
}

They both do the same (which btw does not involve change the array in place), but which one do you think cost less for a developer to maintain?

Hope i give you some thoughts inputs

1 Like

Not at all: in general programming imperatively (ie telling the computer exactly what it should do) will be more efficient if you’re careful. But you need to bear in mind that under the hood, the built in method is doing the same thing, and the extra overhead from extra function calls is likely to be tiny. So you’re exchanging ease of coding/maintainability/ease of testing for manually writing tight loops — which is totally fine, and completely appropriate in some cases. But oftentimes you don’t need to write imperative code, the procedural version (where you just say “do this operation, I don’t care how it works under-the-hood”) may be a better option. For one thing, less code generally means less chance of bugs — for example, in the loops Vs array methods case, there is no chance of off-by-one errors if you use iteration methods like filter

2 Likes

That’s rarely comes to my mind, always thinking more about machine perfomance than mine :smiley: Thank you again, will bear this thought in mind from now on.

The problem is that I always want to know how things work under the hood :smiley: I mean it’s OK, I get better understanding because of it, but sometimes it slows me down. Anyway, thank you for advice! Appreciate it :slight_smile:

This might be of interest if you want some code to read: there is a library called Lodash which contains a huge set of utility methods for JS (basic things like filter and map, and a vast amount more), built to be very fast. In some cases, it used to be [much] faster than native implementations (I don’t know if that is still true). It’s source code is pretty readable, and you can see how each method works (warning: it has a fair few utility methods that it uses internally, so there is a bit of back and forth figuring out how each one works).

It’s based on [it’s a fork of] an earlier library called Underscore, which has a heavily annotated codebase (as an aside, reading and playing around with that annotated code is basically how I learned JS). There is also [old, but very good and still applicable] a book, Functional Javascript which uses Underscore to teach the concepts

2 Likes

Definitely gonna check those out! Thanks again :slight_smile: