Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Alphanumeric sorting using JavaScript
We have a mixed array that we need to sort by alphabet and then by digit. This requires a custom sorting function that handles both alphabetical and numerical parts correctly.
const arr = ['Ab-1', 'Ab-11', 'Ab-12', 'ab-10', 'ab-100', 'ab-101', 'ab2', 'ab-3', 'ab-105'];
console.log("Original array:", arr);
Original array: [ 'Ab-1', 'Ab-11', 'Ab-12', 'ab-10', 'ab-100', 'ab-101', 'ab2', 'ab-3', 'ab-105' ]
The Problem with Standard Sort
JavaScript's default string sort doesn't handle numbers correctly. It treats "10" as smaller than "2" because it compares character by character.
const testArr = ['item-10', 'item-2', 'item-1'];
testArr.sort();
console.log("Standard sort:", testArr);
Standard sort: [ 'item-1', 'item-10', 'item-2' ]
Alphanumeric Sorting Solution
We need to split each string into alphabetical and numerical parts, then compare them separately:
const arr = ['Ab-1', 'Ab-11', 'Ab-12', 'ab-10', 'ab-100', 'ab-101', 'ab2', 'ab-3', 'ab-105'];
const alphaNumericSort = (arr = []) => {
arr.sort((a, b) => {
const aPart = a.split('-');
const bPart = b.split('-');
// First compare alphabetical parts (case-insensitive)
const alphaCompare = aPart[0].toLowerCase().localeCompare(bPart[0].toLowerCase());
if (alphaCompare !== 0) {
return alphaCompare;
}
// If alphabetical parts are same, compare numerical parts
return parseInt(aPart[1]) - parseInt(bPart[1]);
});
};
alphaNumericSort(arr);
console.log("Sorted array:", arr);
Sorted array: [ 'Ab-1', 'ab-3', 'ab-10', 'Ab-11', 'Ab-12', 'ab-100', 'ab-101', 'ab-105' ]
How It Works
The sorting function works in three steps:
- Split: Divides each string at the hyphen to separate text and numbers
-
Compare Text: Uses
localeCompare()for case-insensitive alphabetical comparison - Compare Numbers: Converts string numbers to integers for proper numerical sorting
Alternative: Handling Different Separators
For strings with various separators or formats, use a more flexible approach with regular expressions:
const mixedArr = ['item1', 'item-10', 'item_2', 'item.11'];
const flexibleSort = (arr) => {
return arr.sort((a, b) => {
// Extract text and number parts using regex
const aMatch = a.match(/^([a-zA-Z]+)[\-_.]?(\d+)$/);
const bMatch = b.match(/^([a-zA-Z]+)[\-_.]?(\d+)$/);
if (!aMatch || !bMatch) return a.localeCompare(b);
const textCompare = aMatch[1].toLowerCase().localeCompare(bMatch[1].toLowerCase());
if (textCompare !== 0) return textCompare;
return parseInt(aMatch[2]) - parseInt(bMatch[2]);
});
};
const sortedMixed = flexibleSort([...mixedArr]);
console.log("Flexible sort:", sortedMixed);
Flexible sort: [ 'item1', 'item_2', 'item-10', 'item.11' ]
Conclusion
Alphanumeric sorting requires custom comparison logic that separates text from numbers. Use localeCompare() for text and convert strings to integers for proper numerical ordering.
