DEV Community

Cover image for JavaScript Quick Tip: Quickly Filter Out All Falsy Values From An Array
Oliver Jumpertz
Oliver Jumpertz

Posted on • Edited on • Originally published at oliverjumpertz.com

7 1

JavaScript Quick Tip: Quickly Filter Out All Falsy Values From An Array

Working with arrays in a functional way has mostly become the default when working with JavaScript these days. Why should you use a traditional imperative loop, like for, for..of, while, do..while, etc., when you can use map, filter, and forEach?

These functional methods have one caveat, though: You can never throw from them without aborting the whole pipeline.

someArray.map((value) => {
  if (someConditionMet) {
    throw new Error('...'); // this is not the best idea...
  }
  // ...
  return someValidValue;
});
Enter fullscreen mode Exit fullscreen mode

So what do you do then? Well, you can return null to mark that you have an invalid result.

someArray.map((value) => {
  if (someConditionMet) {
    return null; // now the pipeline can continue
  }
  // ...
  return someValidValue;
});
Enter fullscreen mode Exit fullscreen mode

That's fine. If you don't want your pipeline to abort, you can continue using null values as a marker for "this didn't work out".

But what if you want to get rid of those values afterward? Perhaps something like this?

someArray.map((value) => {
  if (someConditionMet) {
    return null; // now the pipeline can continue
  }
  // ...
  return someValidValue;
}).filter((value) => value);
Enter fullscreen mode Exit fullscreen mode

This leaves you only with valid values, which is perfectly fine, but we can make this even shorter.

The Code

JavaScript has first-class functions. You can pass any function reference to any other function that expects a function as this particular argument. And the Boolean constructor is actually the function responsible to define truthy and falsy.

const array = [1, null, undefined, 0, 2, "", 4];

const result = array.filter(Boolean);
Enter fullscreen mode Exit fullscreen mode

When the filter step of this pipeline has run, you only have all truth values left, and can continue working with them without having to handle special cases like null or undefined.

The Whole Tip As An Image

If you like visual content more, or if you want to store it for later, I put all this into one image for you. I hope you like it!

A picture showcasing the above code

Before You Leave

If you would love to read even more content like this, feel free to visit me on Twitter or LinkedIn.

I'd love to count you as my ever-growing group of awesome friends!

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (4)

Collapse
 
aminnairi profile image
Amin

Hi Oliver and thanks for your interesting well written article!

In some of my project where I need it, I like to create a filterMap function which allows me to map values to something else, just like we would with the map and get only truthy values in the JavaScript sense.

const filterMap = (callback, items) => {
  return items.reduce((oldItems, item) => {
    const newItem = callback(item);

    if (newItem) {
      return [...oldItems, newItem];
    }

    return oldItems;
  }, []);
};

const getElementById = (identifier) => {
  if (Math.random() > 0.5) {
    return `Element#${identifier}`;
  }

  return null;
};

const identifiers = [
  "paragraph",
  "title",
  "users",
  "answers"
];

const elements = filterMap(getElementById, identifiers);

console.log(elements);
// [ 'Element#paragraph', 'Element#users', 'Element#answers' ]
Enter fullscreen mode Exit fullscreen mode

The pro of using reduce instead of map combined with filter is mainly performance since the reduce call will do one pass where the map and filter will do it in two passes.

Often, this is a recurring pattern and when I see that I am doing a mapping and a filtering, I know that I can do it in one reduce.

Collapse
 
oliverjumpertz profile image
Oliver Jumpertz

You are right but it can hurt readability.

Try immutable-js, it has lazy pipeline sequences which work through transducers. No matter how many operations you pipe, only one pass. ☺️

Collapse
 
devdufutur profile image
Rudy Nappée

Even shorter : arr.filter(i => i) 😅👌

Collapse
 
hasnaindev profile image
Muhammad Hasnain

arr.filter(Boolean) is much more readable IMO.

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay