Gathering detailed insights and metrics for natural-orderby
Gathering detailed insights and metrics for natural-orderby
Gathering detailed insights and metrics for natural-orderby
Gathering detailed insights and metrics for natural-orderby
fast-sort
Fast easy to use and flexible sorting with TypeScript support
@shelf/fast-natural-order-by
Lightweight and performant natural sorting of arrays and collections by differentiating between unicode characters, numbers, dates, etc. 150,000x faster fork of natural-orderby for longer strings
@leondreamed/fast-sort
Fast easy to use and flexible sorting with TypeScript support
angular-naturalsort
This repo contains several variations on a library for handling natural sorting when using the `orderBy` filter. It can also optionally be used as a standalone function by injecting the `naturalSort` service into your controller or other object.
Lightweight (< 1.6kB gzipped) and performant natural sorting of arrays and collections by differentiating between unicode characters, numbers, dates, etc.
npm install natural-orderby
Typescript
Module System
Min. Node Version
Node Version
NPM Version
TypeScript (97.55%)
JavaScript (2.45%)
Total Downloads
284,817,775
Last Day
341,196
Last Week
2,046,957
Last Month
8,574,354
Last Year
81,660,756
MIT License
64 Stars
158 Commits
11 Forks
2 Watchers
11 Branches
6 Contributors
Updated on May 09, 2025
Minified
Minified + Gzipped
Latest Version
5.0.0
Package Id
natural-orderby@5.0.0
Unpacked Size
70.75 kB
Size
13.88 kB
File Count
11
NPM Version
10.7.0
Node Version
18.20.4
Published on
Nov 18, 2024
Cumulative downloads
Total Downloads
Last Day
15.3%
341,196
Compared to previous day
Last Week
6.4%
2,046,957
Compared to previous week
Last Month
0%
8,574,354
Compared to previous month
Last Year
26%
81,660,756
Compared to previous year
32
Lightweight (< 1.6kB gzipped) and performant natural sorting of arrays and collections by differentiating between unicode characters, numbers, dates, etc.
People sort strings containing numbers differently than most sorting algorithms, which sort values by comparing strings in Unicode code point order. This produces an ordering that is inconsistent with human logic.
natural-orderby
sorts the primitive values of Boolean
, Null
, Undefined
, Number
or String
type as well as Date
objects. When comparing strings it differentiates between unicode characters, integer, floating as well as hexadecimal numbers, various date formats, etc. You may sort flat or nested arrays or arrays of objects in a natural sorting order using natural-orderby
.
In addition to the efficient and fast orderBy()
method natural-orderby
also provides the method compare()
, which may be passed to Array.prototype.sort()
.
1# npm 2npm install natural-orderby --save 3 4# yarn 5yarn add natural-orderby
If you´re not using a module bundler or package manager there´s also a global ("IIFE") build hosted on the unpkg CDN. Simply add the following <script>
tag to the bottom of your HTML file:
1<script src="https://unpkg.com/natural-orderby/dist/umd/natural-orderby.production.min.js"></script>
Once you've added natural-orderby
you will have access to the global window.naturalOrderBy
variable.
1// Using ES modules 2import { orderBy } from 'natural-orderby'; 3 4// Using CommonJS modules 5// const { orderBy } = require('natural-orderby'); 6 7const users = [ 8 { 9 username: 'Bamm-Bamm', 10 ip: '192.168.5.2', 11 datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)' 12 }, 13 { 14 username: 'Wilma', 15 ip: '192.168.10.1', 16 datetime: '14 Jun 2018 00:00:00 PDT' 17 }, 18 { 19 username: 'Dino', 20 ip: '192.168.0.2', 21 datetime: 'June 15, 2018 14:48:00' 22 }, 23 { 24 username: 'Barney', 25 ip: '192.168.1.1', 26 datetime: 'Thu, 14 Jun 2018 07:00:00 GMT' 27 }, 28 { 29 username: 'Pebbles', 30 ip: '192.168.1.21', 31 datetime: '15 June 2018 14:48 UTC' 32 }, 33 { 34 username: 'Hoppy', 35 ip: '192.168.5.10', 36 datetime: '2018-06-15T14:48:00.000Z' 37 }, 38]; 39 40const sortedUsers = orderBy( 41 users, 42 [v => v.datetime, v => v.ip], 43 ['desc', 'asc'] 44);
This is the return value of orderBy()
:
1[ 2 { 3 username: 'Dino', 4 ip: '192.168.0.2', 5 datetime: 'June 15, 2018 14:48:00', 6 }, 7 { 8 username: 'Pebbles', 9 ip: '192.168.1.21', 10 datetime: '15 June 2018 14:48 UTC', 11 }, 12 { 13 username: 'Bamm-Bamm', 14 ip: '192.168.5.2', 15 datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)', 16 }, 17 { 18 username: 'Hoppy', 19 ip: '192.168.5.10', 20 datetime: '2018-06-15T14:48:00.000Z', 21 }, 22 { 23 username: 'Barney', 24 ip: '192.168.1.1', 25 datetime: 'Thu, 14 Jun 2018 07:00:00 GMT', 26 }, 27 { 28 username: 'Wilma', 29 ip: '192.168.10.1', 30 datetime: '14 Jun 2018 00:00:00 PDT', 31 }, 32];
orderBy()
Creates an array of elements, natural sorted by specified identifiers
and the corresponding sort orders
. This method implements a stable sort algorithm, which means the original sort order of equal elements is preserved.
It also avoids the high overhead caused by Array.prototype.sort()
invoking a compare function multiple times per element within the array.
1orderBy<T>( 2 collection: ReadonlyArray<T>, 3 identifiers?: ReadonlyArray<Identifier<T>> | Identifier<T> | null, 4 orders?: ReadonlyArray<Order> | Order | null 5 locale?: string 6): Array<T>
Type | Value |
---|---|
Identifier<T> | keyof T | number | (value: T) => unknown |
Order | 'asc' | 'desc' | (valueA: unknown, valueB: unknown) => number |
orderBy()
sorts the elements of an array by specified identifiers and the corresponding sort orders in a natural order and returns a new array containing the sorted elements.
If collection
is an array of primitives, identifiers
may be unspecified. Otherwise, you should specify identifiers
to sort by or collection
will be returned unsorted. An identifier can be expressed by:
collection
is a nested array,collection
is an array of objects,collection
.If orders
is unspecified, all values are sorted in ascending order. Otherwise, specify an order of 'desc'
for descending or 'asc'
for ascending sort order of corresponding values. You may also specify a compare function for an order, which will be invoked by two arguments: (valueA, valueB)
. It must return a number representing the sort order.
If you want to sort unicode strings according to a specific locale, please provide a string value for locale
with a BCP 47 language tag. If the argument is unspecified, the host locale setting will be used.
Note:
orderBy()
always returns a new array, even if the original was already sorted.
1import { orderBy } from 'natural-orderby'; 2 3// Simple numerics 4 5orderBy(['10', 9, 2, '1', '4']); 6// => ['1', 2, '4', 9, '10'] 7 8 9// Floats 10 11orderBy(['10.0401', 10.022, 10.042, '10.021999']); 12// => ['10.021999', 10.022, '10.0401', 10.042] 13 14 15// Float & decimal notation 16 17orderBy(['10.04f', '10.039F', '10.038d', '10.037D']); 18// => ['10.037D', '10.038d', '10.039F', '10.04f'] 19 20 21// Scientific notation 22 23orderBy(['1.528535047e5', '1.528535047e7', '1.528535047e3']); 24// => ['1.528535047e3', '1.528535047e5', '1.528535047e7'] 25 26 27// IP addresses 28 29orderBy(['192.168.201.100', '192.168.201.12', '192.168.21.1']); 30// => ['192.168.21.1', '192.168.201.12', '192.168.21.100'] 31 32 33// Filenames 34 35orderBy(['01asset_0815.png', 'asset_47103.jpg', 'asset_151.jpg', '001asset_4711.jpg', 'asset_342.mp4']); 36// => ['001asset_4711.jpg', '01asset_0815.png', 'asset_151.jpg', 'asset_342.mp4', 'asset_47103.jpg'] 37 38// Filenames - ordered by extension and filename 39 40orderBy( 41 ['01asset_0815.png', 'asset_47103.jpg', 'asset_151.jpg', '001asset_4711.jpg', 'asset_342.mp4'],[v => v.split('.').pop(), v => v] 42); 43// => ['001asset_4711.jpg', 'asset_151.jpg', 'asset_47103.jpg', 'asset_342.mp4', '01asset_0815.png'] 44 45 46// Dates 47 48orderBy(['10/12/2018', '10/11/2018', '10/11/2017', '10/12/2017']); 49// => ['10/11/2017', '10/12/2017', '10/11/2018', '10/12/2018'] 50 51orderBy(['Thu, 15 Jun 2017 20:45:30 GMT', 'Thu, 3 May 2018 17:45:30 GMT', 'Thu, 15 Jun 2017 17:45:30 GMT']); 52// => ['Thu, 15 Jun 2017 17:45:30 GMT', 'Thu, 15 Jun 2018 20:45:30 GMT', 'Thu, 3 May 2018 17:45:30 GMT'] 53 54 55// Money 56 57orderBy(['$102.00', '$21.10', '$101.02', '$101.01']); 58// => ['$21.10', '$101.01', '$101.02', '$102.00'] 59 60 61// Case-insensitive sort order 62 63orderBy(['A', 'C', 'E', 'b', 'd', 'f']); 64// => ['A', 'b', 'C', 'd', 'E', 'f'] 65 66 67// Default ascending sort order 68 69orderBy(['a', 'c', 'f', 'd', 'e', 'b']); 70// => ['a', 'b', 'c', 'd', 'e', 'f'] 71 72 73// Descending sort order 74 75orderBy(['a', 'c', 'f', 'd', 'e', 'b'], null, ['desc']); 76// => ['f', 'e', 'd', 'c', 'b', 'a'] 77 78 79// Custom compare function 80 81orderBy([2, 1, 5, 8, 6, 9], null, [(valueA, valueB) => valueA - valueB]); 82// => [1, 2, 5, 6, 8, 9] 83 84 85// collections 86 87const users = [ 88 { 89 username: 'Bamm-Bamm', 90 ip: '192.168.5.2', 91 datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)' 92 }, 93 { 94 username: 'Wilma', 95 ip: '192.168.10.1', 96 datetime: '14 Jun 2018 00:00:00 PDT' 97 }, 98 { 99 username: 'Dino', 100 ip: '192.168.0.2', 101 datetime: 'June 15, 2018 14:48:00' 102 }, 103 { 104 username: 'Barney', 105 ip: '192.168.1.1', 106 datetime: 'Thu, 14 Jun 2018 07:00:00 GMT' 107 }, 108 { 109 username: 'Pebbles', 110 ip: '192.168.1.21', 111 datetime: '15 June 2018 14:48 UTC' 112 }, 113 { 114 username: 'Hoppy', 115 ip: '192.168.5.10', 116 datetime: '2018-06-15T14:48:00.000Z' 117 }, 118]; 119 120orderBy( 121 users, 122 [v => v.datetime, v => v.ip], 123 ['desc', 'asc'] 124); 125// => [ 126// { 127// username: 'Dino', 128// ip: '192.168.0.2', 129// datetime: 'June 15, 2018 14:48:00', 130// }, 131// { 132// username: 'Pebbles', 133// ip: '192.168.1.21', 134// datetime: '15 June 2018 14:48 UTC', 135// }, 136// { 137// username: 'Bamm-Bamm', 138// ip: '192.168.5.2', 139// datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)', 140// }, 141// { 142// username: 'Hoppy', 143// ip: '192.168.5.10', 144// datetime: '2018-06-15T14:48:00.000Z', 145// }, 146// { 147// username: 'Barney', 148// ip: '192.168.1.1', 149// datetime: 'Thu, 14 Jun 2018 07:00:00 GMT', 150// }, 151// { 152// username: 'Wilma', 153// ip: '192.168.10.1', 154// datetime: '14 Jun 2018 00:00:00 PDT', 155// }, 156// ]
compare()
Creates a compare function that defines the natural sort order and which may be passed to Array.prototype.sort()
.
1compare(options?: CompareOptions): CompareFn
Type | Value |
---|---|
CompareOptions | { order?: 'asc' | 'desc', locale?: string } |
CompareFn | (valueA: unknown, valueB: unknown) => number |
compare()
returns a compare function that defines the natural sort order and which may be passed to Array.prototype.sort()
.
If options
or its property order
is unspecified, values are sorted in ascending sort order. Otherwise, specify an order of 'desc'
for descending or 'asc'
for ascending sort order of values.
If unicode strings should be ordered corresponding to a specific locale setting, specify the according value for the options property locale
. It must be a string with a BCP 47 language tag. If the argument is unspecified, the host locale setting will be used.
1import { compare } from 'natural-orderby'; 2 3// Simple numerics 4 5['10', 9, 2, '1', '4'].sort(compare()); 6// => ['1', 2, '4', 9, '10'] 7 8 9// Floats 10 11['10.0401', 10.022, 10.042, '10.021999'].sort(compare()); 12// => ['10.021999', 10.022, '10.0401', 10.042] 13 14 15// Float & decimal notation 16 17['10.04f', '10.039F', '10.038d', '10.037D'].sort(compare()); 18// => ['10.037D', '10.038d', '10.039F', '10.04f'] 19 20 21// Scientific notation 22 23['1.528535047e5', '1.528535047e7', '1.528535047e3'].sort(compare()); 24// => ['1.528535047e3', '1.528535047e5', '1.528535047e7'] 25 26 27// IP addresses 28 29['192.168.201.100', '192.168.201.12', '192.168.21.1'].sort(compare()); 30// => ['192.168.21.1', '192.168.201.12', '192.168.21.100'] 31 32 33// Filenames 34 35['01asset_0815.jpg', 'asset_47103.jpg', 'asset_151.jpg', '001asset_4711.jpg', 'asset_342.mp4'].sort(compare()); 36// => ['001asset_4711.jpg', '01asset_0815.jpg', 'asset_151.jpg', 'asset_342.mp4', 'asset_47103.jpg'] 37 38 39// Dates 40 41['10/12/2018', '10/11/2018', '10/11/2017', '10/12/2017'].sort(compare()); 42// => ['10/11/2017', '10/12/2017', '10/11/2018', '10/12/2018'] 43 44['Thu, 15 Jun 2017 20:45:30 GMT', 'Thu, 3 May 2018 17:45:30 GMT', 'Thu, 15 Jun 2017 17:45:30 GMT'].sort(compare()); 45// => ['Thu, 15 Jun 2017 17:45:30 GMT', 'Thu, 15 Jun 2018 20:45:30 GMT', 'Thu, 3 May 2018 17:45:30 GMT'] 46 47 48// Money 49 50['$102.00', '$21.10', '$101.02', '$101.01'].sort(compare()); 51// => ['$21.10', '$101.01', '$101.02', '$102.00'] 52 53 54// Case-insensitive sort order 55 56['A', 'C', 'E', 'b', 'd', 'f'].sort(compare()); 57// => ['A', 'b', 'C', 'd', 'E', 'f'] 58 59 60// Default ascending sort order 61 62['a', 'c', 'f', 'd', 'e', 'b'].sort(compare()); 63// => ['a', 'b', 'c', 'd', 'e', 'f'] 64 65 66// Descending sort order 67 68['a', 'c', 'f', 'd', 'e', 'b'].sort(compare({ order: 'desc' })); 69// => ['f', 'e', 'd', 'c', 'b', 'a'] 70 71 72// collections 73 74const users = [ 75 { 76 username: 'Bamm-Bamm', 77 lastLogin: { 78 ip: '192.168.5.2', 79 datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)' 80 }, 81 }, 82 { 83 username: 'Wilma', 84 lastLogin: { 85 ip: '192.168.10.1', 86 datetime: '14 Jun 2018 00:00:00 PDT' 87 }, 88 }, 89 { 90 username: 'Dino', 91 lastLogin: { 92 ip: '192.168.0.2', 93 datetime: 'June 15, 2018 14:48:00' 94 }, 95 }, 96 { 97 username: 'Barney', 98 lastLogin: { 99 ip: '192.168.1.1', 100 datetime: 'Thu, 14 Jun 2018 07:00:00 GMT' 101 }, 102 }, 103 { 104 username: 'Pebbles', 105 lastLogin: { 106 ip: '192.168.1.21', 107 datetime: '15 June 2018 14:48 UTC' 108 }, 109 }, 110 { 111 username: 'Hoppy', 112 lastLogin: { 113 ip: '192.168.5.10', 114 datetime: '2018-06-15T14:48:00.000Z' 115 }, 116 }, 117]; 118 119users.sort((a, b) => compare()(a.lastLogin.ip, b.lastLogin.ip)); 120// => [ 121// { 122// username: 'Dino', 123// lastLogin: { 124// ip: '192.168.0.2', 125// datetime: 'June 15, 2018 14:48:00' 126// }, 127// }, 128// { 129// username: 'Barney', 130// lastLogin: { 131// ip: '192.168.1.1', 132// datetime: 'Thu, 14 Jun 2018 07:00:00 GMT' 133// }, 134// }, 135// { 136// username: 'Pebbles', 137// lastLogin: { 138// ip: '192.168.1.21', 139// datetime: '15 June 2018 14:48 UTC' 140// }, 141// }, 142// { 143// username: 'Bamm-Bamm', 144// lastLogin: { 145// ip: '192.168.5.2', 146// datetime: 'Fri Jun 15 2018 16:48:00 GMT+0200 (CEST)' 147// }, 148// }, 149// { 150// username: 'Hoppy', 151// lastLogin: { 152// ip: '192.168.5.10', 153// datetime: '2018-06-15T14:48:00.000Z' 154// }, 155// }, 156// { 157// username: 'Wilma', 158// lastLogin: { 159// ip: '192.168.10.1', 160// datetime: '14 Jun 2018 00:00:00 PDT' 161// }, 162// }, 163// ]
natural-orderby
is completely written in TypeScript and provides TypeScript declarations.
Inspired by The Alphanum Algorithm from Dave Koelle.
Licensed under the MIT License, Copyright © 2018 - present Olaf Ennen.
See LICENSE for more information.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 1/9 approved changesets -- score normalized to 1
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
12 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-04-28
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More