UPDATE Feb 4, 2022 Yes, as commenter Matthias pointed out, you can let JavaScript implicitly make the conversion of boolean minus boolean to end number a number of -1, 0, or 1.

Original but edited blog post below...


Imagine you have an array like this:


const items = [
  { num: 'one', labels: [] },
  { num: 'two', labels: ['foo'] },
  { num: 'three', labels: ['bar'] },
  { num: 'four', labels: ['foo'] },
  { num: 'five', labels: [] },
];

What you want, is to sort them in a way that all those entries that have a label foo come first, but you don't want to "disturb" the existing order. Essentially you want this to be the end result:

{ num: 'two', labels: ['foo'] },
{ num: 'four', labels: ['foo'] },

{ num: 'one', labels: [] },
{ num: 'three', labels: ['bar'] },
{ num: 'five', labels: [] },

Here's a way to do that:


items.sort(
  (itemA, itemB) =>
    itemB.labels.includes('foo') - itemA.labels.includes('foo')
);
console.log(items);

And the outcome is:

[
  { num: 'two', labels: [ 'foo' ] },
  { num: 'four', labels: [ 'foo' ] },
  { num: 'one', labels: [] },
  { num: 'three', labels: [ 'bar' ] },
  { num: 'five', labels: [] }
]

The simple trick is to turn then test operation into a number (0 or 1) and you can do that with Number.

Boolean minus boolean is operator overloaded to become an integer. From the Node repl...

> true - false
1
> false - true
-1
> false - false
0
> true - true
0

Comments

Matthias

Hi there!

Instead of using Number() on both includes-results, you can just use "itemB.labels.includes('foo') - itemA.labels.includes('foo')".

This works because minus will convert both sides to a number anyway before subtracting.

Best regards

mail@peterbe.com

You're right! I had forgotten about that. I updated the blog post.
Truth be told, I'm not sure it's an improvement because it feels like a quirk whereas casting to a number type feels a bit more "commonstream".

Your email will never ever be published.

Previous:
Brotli compression quality comparison in the real world December 1, 2021 Node, JavaScript
Next:
My site's now NextJS - And I (almost) regret it already December 17, 2021 Django, Node, React, JavaScript
Related by category:
Switching from Next.js to Vite + wouter July 28, 2023 JavaScript
How to SSG a Vite SPA April 26, 2025 JavaScript
An ideal pattern to combine React Router with TanStack Query November 18, 2024 JavaScript
swr compared to @tanstack/react-query August 30, 2024 JavaScript
Related by keyword:
How to sort case insensitively with empty strings last in Django April 3, 2022 Python, Django, PostgreSQL
Find the largest node_modules directories with bash September 30, 2022 Linux, Bash, macOS
How to count the most common lines in a file October 7, 2022 Linux, Bash, macOS
In Python you sort with a tuple June 14, 2013 Python