Compare alphanumeric strings the same way a human would, using a natural order algorithm
Standard sorting: Natural order sorting:
img1.png img1.png
img10.png img2.png
img12.png img10.png
img2.png img12.png
This module provides two functions:
naturalCompare
naturalCompare.caseInsensitive
(alias:naturalCompare.i
)
These functions return a number indicating whether one string should come before, after, or is the same as another string.
They can be easily used with the native .sort()
array method.
This module can compare strings containing any size of number and is heavily tested with a custom benchmark suite to make sure that it is as fast as possible.
# npm
npm install string-natural-compare --save
# yarn
yarn add string-natural-compare
var naturalCompare = require('string-natural-compare');
// Simple case-sensitive sorting
var a = ['z1.doc', 'z10.doc', 'z17.doc', 'z2.doc', 'z23.doc', 'z3.doc'];
a.sort(naturalCompare);
// -> ['z1.doc', 'z2.doc', 'z3.doc', 'z10.doc', 'z17.doc', 'z23.doc']
// Simple case-insensitive sorting
var a = ['B', 'C', 'a', 'd'];
a.sort(naturalCompare.caseInsensitive); // alias: a.sort(naturalCompare.i);
// -> ['a', 'B', 'C', 'd']
// Note:
['a', 'A'].sort(naturalCompare.caseInsensitive); // -> ['a', 'A']
['A', 'a'].sort(naturalCompare.caseInsensitive); // -> ['A', 'a']
// Compare strings containing large numbers
naturalCompare(
'1165874568735487968325787328996865',
'265812277985321589735871687040841'
);
// -> 1
// (Other inputs with the same ordering as this example may yield a different number > 0)
// In most cases we want to sort an array of objects
var a = [
{street: '350 5th Ave', room: 'A-1021'},
{street: '350 5th Ave', room: 'A-21046-b'}
];
// Sort by street (case-insensitive), then by room (case-sensitive)
a.sort(function(a, b) {
return (
naturalCompare.caseInsensitive(a.street, b.street) ||
naturalCompare(a.room, b.room)
);
});
// When text transformation is needed or when doing a case-insensitive sort on a
// large array, it is best for performance to pre-compute the transformed text
// and store it in that object. This way, the text transformation will not be
// needed for every comparison when sorting.
var a = [
{make: 'Audi', model: 'R8'},
{make: 'Porsche', model: '911 Turbo S'}
];
// Sort by make, then by model (both case-insensitive)
a.forEach(function(car) {
car.sortKey = (car.make + ' ' + car.model).toLowerCase();
});
a.sort(function(a, b) {
return naturalCompare(a.sortKey, b.sortKey);
});
It is possible to configure a custom alphabet to achieve a desired character ordering.
// Estonian alphabet
naturalCompare.alphabet = 'ABDEFGHIJKLMNOPRSŠZŽTUVÕÄÖÜXYabdefghijklmnoprsšzžtuvõäöüxy';
['t', 'z', 'x', 'õ'].sort(naturalCompare);
// -> ['z', 't', 'õ', 'x']
// Russian alphabet
naturalCompare.alphabet = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя';
['Ё', 'А', 'б', 'Б'].sort(naturalCompare);
// -> ['А', 'Б', 'Ё', 'б']
Note: Putting numbers in the custom alphabet can cause undefined behaviour.