#javascript #sorting
#javascript #сортировка
Вопрос:
У меня есть массив символов, который я хочу отсортировать:
const arr = ['z', 'a', 'Z', 'A'];
Я хочу, чтобы порядок сортировки был следующим: символы верхнего регистра в алфавитном порядке, за которыми следуют символы нижнего регистра в алфавитном порядке:
['A', 'Z', 'a', 'z']
Это тривиально выполнить с помощью .sort()
без каких-либо параметров:
const arr = ['z', 'a', 'Z', 'A'];
arr.sort();
console.log(arr);
Но как можно localeCompare
использовать для определения одинакового относительного положения каждого символа? Опция caseFirst выглядела многообещающе:
Следует ли сортировать сначала верхний или нижний регистр. Возможные значения «upper», «lower» или «false» (используйте языковой стандарт по умолчанию); значение по умолчанию равно «false». Этот параметр можно задать с помощью свойства options или с помощью ключа расширения Unicode; если предоставлены оба параметра, свойство options имеет приоритет.
Но, похоже, это не делает того, что я хочу. Я перепробовал много вариантов:
// Desired result: ['A', 'Z', 'a', 'z']
const arr = ['z', 'a', 'Z', 'A'];
arr.sort((a, b) => a.localeCompare(b));
console.log(arr);
arr.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: 'upper' }));
console.log(arr);
arr.sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'case', caseFirst: 'upper' }));
console.log(arr);
arr.sort((a, b) => a.localeCompare(b, 'en', { caseFirst: 'upper' }));
console.log(arr);
arr.sort((a, b) => a.localeCompare(b, 'kf', { caseFirst: 'upper' }));
console.log(arr);
Я бы хотел, чтобы он выполнялся аналогично .sort()
(по крайней мере, для алфавитных символов), который сравнивает кодовую точку каждого символа:
['A', 'Z', 'a', 'z'].forEach((char) => {
console.log(char.charCodeAt());
});
Конечно, я знаю, что могу просто избежать localeCompare
и использовать .sort()
без обратного вызова или использовать charCodeAt
метод, описанный выше:
const arr = ['z', 'a', 'Z', 'A'];
arr.sort((a, b) => a.charCodeAt() - b.charCodeAt());
console.log(arr);
Но как бы я это сделал, используя localeCompare
?
Комментарии:
1. Я вознагражу за хороший ответ.
2. Хорошего ответа нет, как показывает ваш очень хорошо написанный вопрос. Единственный ответ — отфильтровать два массива (верхний, нижний), отсортировать каждый с помощью
localeCompare()
then.merge()
, а затем снова собрать вместе.3. Было бы полезно узнать, какие функции из
localeCompare
вы хотели.4. @Kaiido Какие угодно функции, которые могут сравниваться лексикографически, по крайней мере, для простых алфавитных символов. Я не знаю, что это за функции и существуют ли они — подозреваю, что нет, — но если они есть, я не придирчивый. Я могу легко выполнить это без
localeCompare
, но мне просто было любопытно, можно ли это как-тоlocaleCompare
использовать и для этого. Это выглядит намного приятнее, чем условный оператор, и.sort()
без аргументов работает только при сортировке массивов строк — не для объектов, и не тогда, когда вне контекста сортировки массива.5. Итак … вы хотите использовать,
localeCompare
просто потому, что это выглядит хорошо? На самом деле вам не нужно ничего, что он делает, например, рассматривалé
раньшеf
?
Ответ №1:
Удалось отсортировать ваш массив лексикографически, используя это.
const lexicalCompare = (a, b) =>
a < b ? -1 : (a > b ? 1 : 0);
const arr = ['z', 'a', 'Z', 'A'];
console.log(arr.sort(lexicalCompare));
Комментарии:
1. Это то же самое, что ни одна операция сортировки не сказала, что они не хотят. Они хотят использовать
localeCompare
(по каким причинам, я не знаю)