npm package: @jcayzac/utils-sorters
Description: Composable sorting algorithms for sort() or toSorted().
Author: Julien Cayzac
Latest version: 1.1.0

# `@jcayzac/utils-sorters`

> Composable sorting algorithms for `sort()` or `toSorted()`.

[![license][license-src]][license-href]
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]

[Documentation](https://www.jsdocs.io/package/@jcayzac/utils-sorters#package-index)

## Installation

```sh
# pnpm
pnpm add @jcayzac/utils-sorters

# bun
bunx add @jcayzac/utils-sorters

# npm
npx add @jcayzac/utils-sorters

# yarn
yarn add @jcayzac/utils-sorters

# deno
deno add npm:@jcayzac/utils-sorters
```

## Usage

```ts
import * as sorters from '@jcayzac/utils-sorters'

const data = [{a:'bbb',b:20},{a:'ccc',b:4},{a:'aab',b:2},{a:'zzz',b:8},{a:'fff',b:18}]

// Sort by 'a' property, reverse-lexicographically
data.toSorted(sorters.reversed(sorters.lexicographic(({a}) => a)))
/* output: */ [
  { a: "zzz", b: 8 },
  { a: "fff", b: 18 },
  { a: "ccc", b: 4 },
  { a: "bbb", b: 20 },
  { a: "aab", b: 2 }
]

// Sort by 'b' property, numerically, in descending order
data.toSorted(sorters.descending(({b}) => b))
/* output: */ [
  { a: "bbb", b: 20 },
  { a: "fff", b: 18 },
  { a: "zzz", b: 8 },
  { a: "ccc", b: 4 },
  { a: "aab", b: 2 }
]

// Same thing, but done differently
data.toSorted(sorters.reversed(sorters.ascending(({b}) => b)))

// Sort lexicographically by `${a} = ${b}`
data.toSorted(sorters.lexicographic(({a,b}) => `${a} = ${b}`))
/* output: */ [
  { a: "aab", b: 2 },
  { a: "bbb", b: 20 },
  { a: "ccc", b: 4 },
  { a: "fff", b: 18 },
  { a: "zzz", b: 8 }
]

// Sort dates in descending order
// If no transformer is provided, both ascending() and descending() just coerce items to numbers
const dates = [new Date('2021-01-01'), new Date('2020-01-01'), new Date('2022-01-01')]
dates.toSorted(sorters.descending())
/* output: */ [
  2022-01-01T00:00:00.000Z,
  2021-01-01T00:00:00.000Z,
  2020-01-01T00:00:00.000Z
]

// Sort URLs lexicographically
// If no transformer is provided, lexicographic() just coerces items to strings
const urls = [
  new URL('https://example.xyz/foo'),
  new URL('https://example.com/foo'),
  new URL('https://example.net/foo'),
  new URL('https://example.org/foo'),
  new URL('https://example.dev/foo'),
]
urls.toSorted(sorters.lexicographic())
/* output: */ [
  new URL('https://example.com/foo'),
  new URL('https://example.dev/foo'),
  new URL('https://example.net/foo'),
  new URL('https://example.org/foo'),
  new URL('https://example.xyz/foo')
]
```

## Like it? Buy me a coffee!

If you like anything here, consider buying me a coffee using one of the following platforms:

[![GitHub Sponsors](https://img.shields.io/badge/GitHub%20Sponsors-E30074?logo=github&logoColor=fff&style=for-the-badge)](https://github.com/sponsors/jcayzac) [![Revolut](https://img.shields.io/badge/Revolut-E30074?logo=revolut&logoColor=fff&style=for-the-badge)](https://revolut.me/julienswap) [![Wise](https://img.shields.io/badge/Wise-E30074?logo=wise&logoColor=fff&style=for-the-badge)](https://wise.com/pay/me/julienc375) [![Ko-Fi](https://img.shields.io/badge/Ko--Fi-E30074?logo=kofi&logoColor=fff&style=for-the-badge)](https://ko-fi.com/jcayzac) [![PayPal](https://img.shields.io/badge/PayPal-E30074?logo=paypal&logoColor=fff&style=for-the-badge)](https://paypal.me/jcayzac)

---
[license-src]: https://img.shields.io/github/license/jcayzac/copepod-modules?style=for-the-badge&colorA=18181B&colorB=E30074&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Im0yNDMuMTQgMTMxLjU0bC0zMi04MGExMiAxMiAwIDAgMC0xMy43My03LjI1TDE0MCA1N1Y0MGExMiAxMiAwIDAgMC0yNCAwdjIyLjM3TDUzLjQgNzYuMjlhMTIgMTIgMCAwIDAtOC41NCA3LjI1bC0zMiA3OS45MkExMiAxMiAwIDAgMCAxMiAxNjhjMCAxMi4xMyA2LjIgMjIuNDMgMTcuNDUgMjlBNTUgNTUgMCAwIDAgNTYgMjA0YTU1IDU1IDAgMCAwIDI2LjU1LTdDOTMuOCAxOTAuNDMgMTAwIDE4MC4xMyAxMDAgMTY4YTEyIDEyIDAgMCAwLS44Ni00LjQ2TDcyLjM4IDk2LjY1TDExNiA4N3YxMTdoLTEyYTEyIDEyIDAgMCAwIDAgMjRoNDhhMTIgMTIgMCAwIDAgMC0yNGgtMTJWODEuNjNsNDAuNDItOWwtMjMuNTYgNTguOUExMiAxMiAwIDAgMCAxNTYgMTM2YzAgMTIuMTMgNi4yIDIyLjQzIDE3LjQ1IDI5YTUzLjc4IDUzLjc4IDAgMCAwIDUzLjEgMGMxMS4yNS02LjU3IDE3LjQ1LTE2Ljg3IDE3LjQ1LTI5YTEyIDEyIDAgMCAwLS44Ni00LjQ2TTU2IDE4MGMtMy43MSAwLTE4LTEuODctMTkuODEtMTAuMThMNTYgMTIwLjMxbDE5LjgxIDQ5LjUxQzc0IDE3OC4xMyA1OS43MSAxODAgNTYgMTgwbTE0NC0zMmMtMy43MSAwLTE4LTEuODctMTkuODEtMTAuMThMMjAwIDg4LjMxbDE5LjgxIDQ5LjUxQzIxOCAxNDYuMTMgMjAzLjcxIDE0OCAyMDAgMTQ4Ii8+PC9zdmc+
[license-href]: https://github.com/jcayzac/copepod-modules/blob/main/LICENSE
[npm-version-src]: https://img.shields.io/npm/v/@jcayzac/utils-sorters?logo=npm&style=for-the-badge&colorA=18181B&colorB=E30074
[npm-version-href]: https://npmjs.com/package/@jcayzac/utils-sorters
[npm-downloads-src]: https://img.shields.io/npm/dm/@jcayzac/utils-sorters?style=for-the-badge&colorA=18181B&colorB=E30074&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Im0yMjkuNjYgMTQxLjY2bC05NiA5NmE4IDggMCAwIDEtMTEuMzIgMGwtOTYtOTZBOCA4IDAgMCAxIDMyIDEyOGg0MFY0OGExNiAxNiAwIDAgMSAxNi0xNmg4MGExNiAxNiAwIDAgMSAxNiAxNnY4MGg0MGE4IDggMCAwIDEgNS42NiAxMy42NiIvPjwvc3ZnPg==
[npm-downloads-href]: https://npmjs.com/package/@jcayzac/utils-sorters
[bundle-src]: https://img.shields.io/bundlephobia/min/@jcayzac/utils-sorters?style=for-the-badge&colorA=18181B&colorB=E30074&logo=data:image/svg%2bxml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI1NiAyNTYiPjxwYXRoIGZpbGw9IiNmZmZmZmYiIGQ9Ik0yNDAgMTUydjI0YTE2IDE2IDAgMCAxLTE2IDE2SDExNS45M2E0IDQgMCAwIDEtMy4yNC02LjM1TDE3NC4yNyAxMDFhOC4yMSA4LjIxIDAgMCAwLTEuMzctMTEuM2E4IDggMCAwIDAtMTEuMzcgMS42MWwtNzIgOTkuMDZhNCA0IDAgMCAxLTMuMjggMS42M0gzMmExNiAxNiAwIDAgMS0xNi0xNnYtMjIuODdjMC0xLjc5IDAtMy41Ny4xMy01LjMzYTQgNCAwIDAgMSA0LTMuOEg0OGE4IDggMCAwIDAgOC04LjUzYTguMTcgOC4xNyAwIDAgMC04LjI3LTcuNDdIMjMuOTJhNCA0IDAgMCAxLTMuODctNWMxMi00My44NCA0OS42Ni03Ny4xMyA5NS41Mi04Mi4yOGE0IDQgMCAwIDEgNC40MyA0VjcyYTggOCAwIDAgMCA4LjUzIDhhOC4xNyA4LjE3IDAgMCAwIDcuNDctOC4yN1Y0NC42N2E0IDQgMCAwIDEgNC40My00YTExMi4xOCAxMTIuMTggMCAwIDEgOTUuOCA4Mi4zM2E0IDQgMCAwIDEtMy44OCA1aC0yNC4wOGE4LjE3IDguMTcgMCAwIDAtOC4yNSA3LjQ3YTggOCAwIDAgMCA4IDguNTNoMjcuOTJhNCA0IDAgMCAxIDQgMy44NmMuMDYgMS4zNy4wNiAyLjc1LjA2IDQuMTQiLz48L3N2Zz4=
[bundle-href]: https://bundlephobia.com/result?p=@jcayzac/utils-sorters