I have an array that contains negative numbers, empty string ''
, Zero 0
and positive numbers. I want to sort the array so that empty string ''
always shows at the end.
[-1, 2, '', -2, 0, 4, '', 1,5,0, -5, 7, 11, '',3]
and expected output
[-5, -2, -1, 0, 0, 1, 2, 3, 4, 5, 7, 11, '', '', '']
4
Answers
you can write a custom sort function so that empty strings are moved to the back of the array
[...arr]
if you don’t want to mutate your original array since sort mutates original array.You can prioritize the comparison with the empty string in the sorting condition.
If
b
is empty, place it in front; but ifa
is empty, place it at the end.Where both
a
andb
are non-empty, perform a standarda - b
return.If you want to always keep the empty values at the end, you need to track sorting direction:
I would personally define some general purpose sort helpers that are useful in all sorts of
sort()
scenarios.Let’s first look at the answer without knowing what the helpers do:
As you can see this solution looks relatively simple. Note that the second sorting criteria
asc
will apply to both numbers and strings. So if the strings are non-empty, they will also be sorted in ascending order.Helpers
Now, let’s explain the general purpose helpers (see collapsed snippet).
I’ll use the term comparator quite a bit. A comparator is a function that accepts 2 arguments, then returns a number to tell
sort()
how the 2 arguments should be sorted.A negative value indicates that the first argument should be placed before the second. A positive value indicates that the first argument should be placed after the second argument. Zero indicates that both arguments can be considered equal.
A basic example of an comparator can be seen in the explanation for
asc
.fallThrough
fallThrough
allows us to pass multiple comparator functions. If the first comparator says that the values are equal, then the next comparator is invoked. If the second comparator also says the values are equal, we’ll move on the the third.This goes on until one of the comparators says which value comes first. If there are no more comparators available, the values are considered equal.
Here is an example without the use of the other helpers:
The above will first try to sort based on last name. If those are equal we sort by first name.
by
by
is a simple helper that accepts a mapping function and a comparator. It applies the mapping function to both comparator arguments. The purpose is mainly to reduce code repetition.When looking in the example above we can see that we access
personA.lastName
andpersonB.lastName
, which are the same mappings for both compared items. By usingby
we can simplify this example:Note that you don’t have to use
fallThrough
. If have just a single sorting criteria then the following will suffice:asc
&desc
asc
anddesc
are comparators based on<
(less than) and>
(greater then).The definition of
asc
is:Which might be hard to read if you’re still new to JavaScript. It could also be written as:
The more cryptic version uses
-(a < b)
, which evaluates to-(true)
, which in turn evaluates to-1
. Since-1
is a truthy value||
short circuits and-1
is returned. If this first expression is not true, then it evaluates to-(false)
, which will produce-0
. Since-0
is a falsy value we’ll move on to the second operand of||
. Here we’ll do the same ifa > b
is true then+(true)
will result in1
for the return value. Ifa > b
is false (aka the values are equal) then+(false)
will return0
.Note that when comparing strings with
<
and>
they are compared based on code point value of the characters.desc
is the same asasc
, but produces the reverse order by swapping the comparator arguments.front
&back
front
andback
are there to simplify boolean logic in sorting.Is kind of hard to read. Are the strings placed in the front or in the back? Let’s think for a second.
typeof item === "string"
produces atrue
orfalse
value.true
will coerce into1
,false
into0
. We are sorting in ascending order, so we are sorting from small to high.1
is greater than0
, meaning that strings are placed in the back.You don’t want to do this kind of thinking when reading code. Therefore I’ve provided the
front
andback
helpers. These expect you to pass a test and make the above a lot more readable.In this version you can instantly see that strings are placed at the back of the array.