У меня есть список объектов, которые я хочу отсортировать на основе поля attr
типа строки. Я пытался с помощью-
list.sort(function (a, b) {
return a.attr - b.attr
})
но обнаружил, что -
не похоже на работу со строками в JavaScript. Как я могу отсортировать список объектов на основе атрибута с типом строки?
javascript
string
airportyh
источник
источник
JavaScript case insensitive string comparison
на stackoverflow.com/questions/2140627/…Javascript : remove accents/diacritics in strings
На stackoverflow.com/questions/990904/…Ответы:
Используйте
String.prototype.localeCompare
согласно вашему примеру:Мы заставляем a.attr быть строкой, чтобы избежать исключений.
localeCompare
поддерживается с Internet Explorer 6 и Firefox 1. Вы также можете увидеть следующий код, который не соответствует локали:источник
localeCompare()
не сталкивается с этой проблемой, но не понимает числовых значений, поэтому вы получите ["1", "10", "2"], как при сортировке сравнений в большинстве языков. если вы хотите выполнить сортировку для своего интерфейса пользовательского интерфейса, посмотрите алгоритм алфавитно-естественной сортировки stackoverflow.com/questions/4340227/… или stackoverflow.com/questions/4321829/…localeCompare()
поддерживается только в современных браузерах: IE11 + в момент написания, см developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...localeCompare()
многих версий, но не поддерживает указание локали до версии 11. Обратите внимание также на вопросы, связанные с Dead.Rabit.Обновленный ответ (октябрь 2014 г.)
Я был действительно раздражен этим естественным порядком сортировки строк, поэтому я потратил некоторое время на изучение этой проблемы. Надеюсь, это поможет.
Короче говоря
localeCompare()
поддержка персонажей крутая, просто используйте ее. Как указаноShog9
, ответ на ваш вопрос:Обнаружены ошибки во всех пользовательских реализациях "естественного порядка сортировки строк" javascript
Существует довольно много пользовательских реализаций, пытающихся сделать сравнение строк, более точно названное «естественным порядком сортировки строк».
«Играя» с этими реализациями, я всегда замечал какой-то странный выбор «естественного порядка сортировки» или, скорее, ошибки (или упущения в лучших случаях).
Как правило, специальные символы (пробел, тире, амперсанд, скобки и т. Д.) Обрабатываются неправильно.
Затем вы обнаружите, что они выглядят смешанными в разных местах, обычно это может быть:
Когда можно было бы ожидать, что все специальные символы будут «сгруппированы» в одном месте, за исключением, возможно, специального символа пробела (который всегда будет первым символом). То есть либо все перед цифрами, либо все между цифрами и буквами (строчные и прописные буквы «вместе» один за другим) или все после букв.
Мой вывод заключается в том, что все они не обеспечивают последовательный порядок, когда я начинаю добавлять едва необычные символы (например, символы с диакритическими знаками или символами, такими как тире, восклицательный знак и т. Д.).
Исследование пользовательских реализаций:
Natural Compare Lite
https://github.com/litejs/natural-compare-lite : не удается последовательно сортировать https://github.com/litejs/natural-compare-lite/issues/1 и http://jsbin.com/bevututodavi/ 1 / edit? Js, консоль , базовая сортировка латинских символов http://jsbin.com/bevututodavi/5/edit?js,consoleNatural Sort
https://github.com/javve/natural-sort : сбой при последовательной сортировке, смотрите выпуск https://github.com/javve/natural-sort/issues/7 и смотрите сортировку основных латинских символов http: // jsbin. ком / cipimosedoqe / 3 / редактировать? JS, консолиJavascript Natural Sort
https://github.com/overset/javascript-natural-sort : похоже, с февраля 2012 года пренебрегают, не удается последовательно сортировать, см. выпуск https://github.com/overset/javascript-natural-sort/issues/16Alphanum
http://www.davekoelle.com/files/alphanum.js , Сбой при последовательной сортировке, см. http://jsbin.com/tuminoxifuyo/1/edit?js,consoleРеализация в браузере "естественного порядка сортировки строк" через
localeCompare()
localeCompare()
Самая старая реализация (без аргументов locales и options) поддерживается IE6 +, см. http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx (прокрутите вниз до localeCompare ( ) метод). ВстроенныйlocaleCompare()
метод намного лучше справляется с сортировкой, даже международных и специальных символов. Единственная проблема при использованииlocaleCompare()
метода заключается в том, что «используемый языковой стандарт и порядок сортировки полностью зависят от реализации». Другими словами, при использовании localeCompare, например stringOne.localeCompare (stringTwo): Firefox, Safari, Chrome & IE имеют другой порядок сортировки для строк.Исследование нативных реализаций браузера:
Сложность «порядка естественной сортировки строк»
Реализация надежного алгоритма (то есть согласованного, но охватывающего широкий диапазон символов) является очень сложной задачей. UTF8 содержит более 2000 символов и охватывает более 120 сценариев (языков) . Наконец, есть некоторая спецификация для этих задач, она называется «Алгоритм сопоставления Unicode», которую можно найти по адресу http://www.unicode.org/reports/tr10/ . Вы можете найти больше информации по этому вопросу, который я разместил /software/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order
Окончательный вывод
Поэтому, учитывая текущий уровень поддержки, предоставляемый пользовательскими реализациями javascript, с которыми я сталкивался, мы, вероятно, никогда не увидим ничего похожего на поддержку всех этих символов и сценариев (языков). Следовательно, я бы предпочел использовать родной метод браузера localeCompare (). Да, у него есть и обратная сторона: он непоследователен в разных браузерах, но базовое тестирование показывает, что он охватывает гораздо более широкий диапазон символов, что позволяет получить четкие и содержательные порядки сортировки.
Таким образом, как указано
Shog9
, ответ на ваш вопрос:Дальнейшее чтение:
Благодаря хорошему ответу Shog9, который, как мне кажется, поставил меня в «правильное» направление
источник
Ответ (в современном ECMAScript)
Или
Описание
Преобразование логического значения в число приводит к следующему:
true
->1
false
->0
Рассмотрим три возможных шаблона:
(x > y) - (y < x)
->1 - 0
->1
(x > y) - (y < x)
->0 - 0
->0
(x > y) - (y < x)
->0 - 1
->-1
(Альтернативный)
+(x > y) || -(x < y)
->1 || 0
->1
+(x > y) || -(x < y)
->0 || 0
->0
+(x > y) || -(x < y)
->0 || -1
->-1
Так что эти логики эквивалентны типичным функциям компаратора сортировки.
источник
localeCompare
и стандартное сравнение дают разные результаты. Что вы ожидаете?["A", "b", "C", "d"].sort((a, b) => a.localeCompare(b))
сортирует в алфавитном порядке без["A", "b", "C", "d"].sort((a, b) => (a > b) - (a < b))
учета регистра, в то время как в порядке кодированияВы должны использовать> или <и == здесь. Таким образом, решение будет:
источник
Функция вложенной троичной стрелки
источник
поскольку строки можно сравнивать непосредственно в JavaScript, это сделает работу
вычитание в функции сортировки используется только тогда, когда требуется не алфавитная (числовая) сортировка и, конечно, она не работает со строками
источник
Я долго беспокоился об этом, поэтому я наконец исследовал это и дал вам эту длинную причудливую причину того, почему вещи такие, какие они есть.
Из спецификации :
Итак, теперь мы переходим к 11.9.6
Вот и все. Оператор тройного равенства, применяемый к строкам, возвращает истину, если аргументы являются абсолютно одинаковыми строками (одинаковой длины и одинаковых символов в соответствующих позициях).
То
===
же самое будет работать в тех случаях, когда мы пытаемся сравнить строки, которые, возможно, поступили из разных источников, но которые мы знаем, в конечном итоге будут иметь одинаковые значения - достаточно распространенный сценарий для встроенных строк в нашем коде. Например, если у нас есть переменная с именемconnection_state
, и мы хотим знать, в каком из следующих состояний['connecting', 'connected', 'disconnecting', 'disconnected']
она находится сейчас, мы можем напрямую использовать===
.Но это еще не все. Чуть выше 11.9.4, есть короткое примечание:
Хм. Что теперь? Струны, полученные извне, могут быть, и, скорее всего, будут странными юникодами, и наши нежные
===
не сделают им должного . НаlocaleCompare
помощь приходит :Теперь мы можем идти домой.
ТЛ; др;
Чтобы сравнить строки в JavaScript, используйте
localeCompare
; если вы знаете, что в строках нет компонентов, отличных от ASCII, потому что они, например, являются внутренними программными константами, то это===
тоже работает.источник
В вашей операции в вашем первоначальном вопросе вы выполняете следующую операцию:
Таким образом, предполагая, что это числа (т.е. item1.attr = "1", item2.attr = "2"), вы все равно можете использовать оператор "===" (или другие строгие оценщики) при условии, что вы гарантируете тип. Следующее должно работать:
Если они буквенно-цифровые, то используйте localCompare ().
источник
Как работают образцы:
источник
источник
источник