Explain Codes LogoExplain Codes Logo

Join strings with a delimiter only if strings are not null or empty

javascript
prompt-engineering
functions
performance
Anton ShumikhinbyAnton Shumikhin·Jan 9, 2025
TLDR

Let's erase those elusive null or empty elements with Array.prototype.filter() and call upon Array.prototype.join() to unite the remaining strings with your chosen delimiter:

const joinNonEmpty = (arr, delim) => arr.filter(Boolean).join(delim); // Example: console.log(joinNonEmpty(['apple', '', 'orange', null, 'banana'], ', ')); // "apple, orange, banana"

Know your alternatives

A touch of lodash magic

If Lodash is part of your arsenal, take advantage of its simple and powerful _.filter and _.join functions:

const _ = require('lodash'); const joinNonEmptyLodash = (arr, delim) => _.join(_.filter(arr, Boolean), delim); // Example: console.log(joinNonEmptyLodash(['apple', '', null, 'banana'], ', ')); // "apple, banana"

This magic Lodash spell provides browser compatibility, including those old IE wizards.

Creating a dynamic concierge

To dynamically manage different fields, such as parts of an address, let's design a flexible function that treats arguments as an array:

function joinIfPresent(delim, ...args) { return args.filter(item => item).join(delim); } // It's like mailing a letter without the postal code: console.log(joinIfPresent(', ', 'Street Name', '', 'City', null, 'Country')); // Street Name, City, Country

Our function avoids using Array.prototype.slice.call(arguments). It's like choosing the stairs instead of the faulty elevator for optimal performance.

Incorporating concise conditional logic

Compactness can yield clarity, too. The ternary operator provides a tidy conditional check:

const joinWithTernary = (arr, delim) => arr.filter(item => item ? true : false).join(delim); // Our fruits have mastered the art of camouflage: console.log(joinWithTernary(['apple', null, 'banana'], '; ')); // "apple; banana"

Brace for edge cases

jQuery's way of joining the party

When jQuery is your party planner, it makes iterating and filtering a breeze:

const joinNonEmptyJQuery = (arr, delim) => $.map(arr, item => item || null).join(delim); // Everyone's invited, but not everyone shows up: $('#element').append(joinNonEmptyJQuery(['<div>apple</div>', '', '<div>banana</div>'], ''));

Difference between null and empty

Just like spotting the difference between a doorknob and a doughnut, null and empty strings can be neatly distinguished by observing its length:

const joinWithoutFalsy = (arr, delim) => arr.filter(str => str && str.length > 0).join(delim); // Got a banana but still looking for the apple: console.log(joinWithoutFalsy(['apple', undefined, 'banana'], ', ')); // "apple, banana"

Stronger types: because variety is the spice of life

The method LOVES diversity. Feed it numbers, objects, or more, and see them blend into a delicious mix of strings:

console.log(joinNonEmpty([42, null, { key: 'value' }, '', 'end'], ' - ')); // "42 - [object Object] - end" - 42 found his way, but the key(value) got lost in translation

Structuring your code sandwich

Your structure is like the bread in a sandwich. Hold firm, but adapt. Consider instances like generating URLs:

const urlParts = ['https://example.com', '', 'page', null]; console.log(joinNonEmpty(urlParts, '/')); // "https://example.com/page"

Forming ways with form fields

Try to combine user input into a string, and witness our joining method carefully skip over empty fields:

const formData = { firstName: 'John', lastName: '', email: '[email protected]', }; console.log(joinNonEmpty(Object.values(formData), ' ')); // "John [email protected]"