Следуя рекомендациям @ Pointy , я сделал функцию сортировки на основе Int.Collator объекта Intl API . Метод String .localeCompare()
похож на метод Collator .compare()
.
/**
* @function sortChars(chars, desc, caps);
* Sort an array of characters in a human readable order.
*
* @param {Array} chars An array of Strings and Numbers.
* @param {Boolean} desc true - sort in descending order
* @default false - sort in ascending order
*
* @param {Boolean} caps true - will place upper case letters first
* @default false - will place lower case letters first
* @return {Array} An array sorted by these criterion:
* space: ' ',
* non-letters: '?',
* numbers: 99,⁰
* lower case letter: 'l',¹
* upper case letter: 'L'¹
*
*//* ⁰Contiguous groups of digits are considered at that value as a whole inside
a String or Number ex. ['1', 99, '100A']
¹The order of case can be changed by the third parameter
*/
const example = ['99', 98, 1, 'one', ' ', 'z', '♞', 'Ĉ', 'Z', 2112, '2111', 'a581', 'aa999999', '?', 'One', 'aA999999'];
const sortChars = (chars, desc, caps) => {
// Ternary to determine case order
let caseType = !caps ? "lower" : "upper";
/*
Initializing Collator Object
numeric: true and sensitivity: "base" are required
to evaluate Numbers properly
Refer to: https://blog.praveen.science/natural-sorting-in-javascript/
*/
const collator = new Intl.Collator(undefined, {
caseFirst: caseType,
numeric: true,
sensitivity: "base"
});
// Uncomment statement below to see option values
// log(check(collator, desc));
const ordered = chars.sort(collator.compare);
// Ternary to determine the direction of returned array
return !desc ? ordered : ordered.reverse();
};
// Sort ascending order
log(sortChars(example));
// Sort descending order
log(sortChars(example, true));
// Sort ascending order and upper case first
log(sortChars(example, false, true));
// Utility to review the options object
function check(collator, desc) {
return Object.assign(Object.fromEntries(Object.entries(collator.resolvedOptions())), {
descendingOrder: desc
});
}
// Utility to log formatted entries to console
function log(data) {
return console.log(JSON.stringify(data));
};
.as-console-wrapper {
word-break: break-word
}