Avoiding falsy values in JavaScript arrays

April 11, 2018 0 Comments

Avoiding falsy values in JavaScript arrays

 

 

tl;dr: use Array.filter(Boolean) to filter out falsy values and avoid errors.

// Fun function that converts a name into a
// 4 all-cap letters display name
const makeDisplayName = name => (
name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, "")
).toUpperCase().slice(0, 4);
const displayNames = [
null, "orange", "apple", "mango", undefined
].filter(Boolean).map(makeDisplayName);
// [ 'ORNG', 'APPL', 'MNG' ]
// vs
const displayNamesErrors = [
null, "orange", "apple", "mango", undefined
].map(makeDisplayName);
// TypeError: Cannot read property 'charAt' of undefined

Boolean when passed any falsy value returns false and when passed a truthy value returns true:

Boolean(false); // false
Boolean(""); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(0); // false
Boolean(NaN); // false
Boolean(1); // true
Boolean("hello"); // true
Boolean(true); // true
Boolean({}); // true
Boolean([]); // true

Note that a valid use case of filtering out falsy values except 0 needs special treatment since, Boolean(0) returns false, hence:

const noFalsyEvenZero = [
NaN,
undefined,
null,
0,
1,
2,
2000,
Infinity
].filter(Boolean);
// [ 1, 2, 2000, Infinity ]
const noFalsyExceptZero = [
NaN,
undefined,
null,
0,
1,
2,
2000,
Infinity
].filter(el => el === 0 || Boolean(el));
// [ 0, 1, 2, 2000, Infinity ]

Usually this happens when you want to compute something over an Array of objects where some of the elements have a property but others don’t.

const companies = [
{
name: null,
employees: [],
founders: []
},
{
name: "orange",
employees: [],
founders: []
},
{
name: "apple",
employees: [],
founders: []
},
{
name: "mango",
employees: [],
locations: []
},
{
employees: [],
founders: []
}
];
const companyNames = companies.map(company => company.name);
// [undefined, "orange", "apple", "mango", undefined]

An issue can occur when you have null or undefined in your list

const makeDisplayName = name => (
name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, "")
).toUpperCase().slice(0, 4);
const companyDisplayNames = [
null,
"orange",
"apple",
"mango",
undefined
].map(makeDisplayName);
// TypeError: Cannot read property 'charAt' of undefined

To avoid this we can filter falsy values out:

const makeDisplayName = name => (
name.charAt(0) + name.slice(1).replace(/a|e|i|o|u/g, "")
).toUpperCase().slice(0, 4);
const companyDisplayNames = [
null,
"orange",
"apple",
"mango",
undefined
].filter(Boolean) // item => item would also work here :)
.map(makeDisplayName);
// [ 'ORNG', 'APPL', 'MNG' ] // No Error :)


Tag cloud