В javascript Infinity
всегда больше любого другого числа, кроме самого себя, а -Infinity
всегда меньше. Что является аналогом этого для символов, то есть каково значение строки c
, для которой c.localCompare(anyString)
всегда будет возвращать (+/-)1 соответственно (очевидно, кроме случая, когда c === anyString
)?
На практике это будет использоваться для сортировки объектов на основе двух флагов и свойства groupName
, которые будут вводиться пользователями в другую часть программного обеспечения в соответствии с ограничениями проверки ввода, поэтому это не будет пустой строкой. (Мне нужно проверить, может ли кто-нибудь «атаковать» скрипт, вставив множество 0xFFFF в приглашение имени.)
Если бы что-то вроде Infinity
существовало, обратный вызов для sort()
выглядел бы так:
(n1, n2) =>
(n1.flag1 ? plusCharInfinity :
n1.flag2 ? minusCharInfinity :
n1.groupName).localeCompare(
n2.flag1 ? plusCharInfinity :
n2.flag2 ? minusCharInfinity :
n2.groupName)
т.е. если flag1 === true
то понизить в низ; если flag2 === true
- продвижение в топ; в противном случае используйте данное значение groupName
.
Также строки могут быть любой длины. Существует максимально возможная кодовая точка UTF-32, но строка из 100 из них больше, чем строка из 99. Я не думаю, что то, о чем вы просите, возможно.
Пустая строка обеспечивает один конец. Бесконечная строка (состоящая только из 0xFFFF
s) обеспечивает другой конец, но не может быть построена.
ОП указывает except when c === anyString
@pilchard
@Toastrackenigma, это справедливо, если их вариант использования не требует пустых строк. Моя точка зрения заключалась в том, что это может быть полезно в качестве нижней границы, но это не аналог -Infinity
, а скорее ближе к Number.MIN_SAFE_INTEGER
Да, это тоже справедливое замечание @pilchard. Однако я не думаю, что такое аналогичное значение существует.
Зачем вызывать ненужную функцию (localeCompare), если вы уже знаете, каким должно быть возвращаемое значение, в случае, если установлены флаги.
Спасибо за идею с нижней границей, @Bergi и @pilchard!
Как указывали другие в комментариях, невозможно создать строки, которые существуют за пределами диапазона допустимых строковых кодовых точек, чтобы обеспечить соблюдение описанных отношений.
Однако, если вы просто хотите реализовать случаи детерминированной сортировки с помощью String.prototype.localeCompare() API ( который, кстати, определяется реализацией), вы можете реализовать его с помощью пользовательских объектов. Вот пример:
const smallest = {
localeCompare(that) {
return Object.is(this, that) ? 0 : -1;
},
};
const largest = {
localeCompare(that) {
return Object.is(this, that) ? 0 : 1;
},
};
console.info(smallest.localeCompare(smallest)); // 0
console.info(largest.localeCompare(largest)); // 0
console.info(smallest.localeCompare(largest)); // -1
console.info(smallest.localeCompare("")); // -1
console.info(smallest.localeCompare("zzzzzzzzzz")); // -1
// etc.
console.info(largest.localeCompare(smallest)); // 1
console.info(largest.localeCompare("")); // 1
console.info(largest.localeCompare("zzzzzzzzzz")); // 1
// etc.
Это на самом деле не работает, потому что несовместимо с "".localeCompare(smallest)
.
Непосредственно аналогичных значений для строк нет, по крайней мере, таких, которые я мог бы легко найти в спецификации.
Пустая строка ""
хорошо работает как нижняя граница, однако, как указывает @pilchard, это также значение, которое вы можете обычно иметь, поэтому оно не так безопасно, как, например. -Infinity
, что всегда даже ниже, чем любое действительное действительное число, отличное от бесконечности.
stringToCompare.localeCompare("");
Верхнюю границу построить сложнее. Теоретически вам нужно иметь строку максимальной длины, где каждый символ является максимальным значением, и вот несколько подходов, которые вы могли бы попробовать получить это значение:
Вы можете попытаться переопределить геттер для свойства length
конкретной строки, чтобы притвориться, что у вас действительно большая строка. Однако в большинстве движков прототип заморожен, и вы не можете его переопределить.
Спецификация JavaScript определяет максимальный размер строк как 253-1 элемента, что требует 16 384 ТБ памяти и, следовательно, невозможно построить.
Однако большинство браузеров ограничивают это число гораздо меньшим числом (которое действительно может поместиться в оперативной памяти, которая у нас есть сегодня): 32-разрядный Chrome: ~ 512 МБ, 64-разрядный Chrome: ~ 1 ГБ, Firefox: ~ 2 ГБ и Safari: ~ 4 ГБ . Есть способы проверить эту длину и построить такую строку, но это было бы пустой тратой памяти и не особенно производительно.
Но есть более простое решение. Если вы согласны с тем, что у вас нет фиксированного максимального значения, вы всегда можете создавать «более высокую» строку каждый раз, когда вам нужно выполнить сравнение.
JavaScript представляет символы как 16-битные числа, что делает максимально возможный символ \uffff
. Если мы создадим строку, аналогичную исходной строке, но имеющую этот символ в начале, то эта новая строка всегда будет больше, чем исходная строка:
stringToCompare.localeCompare(`\uffff${stringToCompare}`);
Использовал вашу идею для более высокой оценки, ура @Toastrackenigma!
Прямого аналога нет. Что касается символов, вы должны учитывать тот факт, что существуют кодовые точки, для представления которых требуется пара символов UTF-16, и, по-видимому, ChatGPT этого не знает.