У меня есть массив строк, которые мне нужно отсортировать в JavaScript, но без учета регистра. Как это сделать?
javascript
sorting
case-insensitive
Жером Верстринг
источник
источник
return a.localeCompare(b, 'en', {'sensitivity': 'base'});
toLowerCase()
когдаlocaleCompare
уже делает это по умолчанию в некоторых случаях. Вы можете прочитать больше о параметрах для передачи здесь: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…items.sort(new Intl.Collator('en').compare)
для повышения производительности. (См. MDN .)РЕДАКТИРОВАТЬ: Обратите внимание, что я изначально написал это, чтобы проиллюстрировать технику, а не иметь в виду производительность. Пожалуйста, также обратитесь к ответу @Ivan Krechetov для более компактного решения.
источник
toLowerCase
дважды в каждой строке; было бы более эффективно хранить пониженные версии строки в переменных..toLowerCase()
несколько раз для каждого элемента в массиве. Например, 45 вызовов функции сравнения при сортировке 10 элементов в обратном порядке.var i = 0; ["z","y","x","w","v","u","t","s","r","q"].sort(function (a, b) {++i; return a.toLowerCase().localeCompare(b.toLowerCase());}); console.log("Calls to Compare: " + i); // i === 45
Настало время вернуться к этому старому вопросу.
Вы не должны использовать решения, основанные на
toLowerCase
. Они неэффективны и просто не работают на некоторых языках (например, на турецком). Предпочитаю это:Проверьте документацию на совместимость браузера и все, что нужно знать об этой
sensitivity
опции.источник
источник
return a === b ? 0 : a > b ? 1 : -1;
["111", "33"]
, мы могли бы хотеть, чтобы это возвратилось,["111", "33"]
потому что 1 предшествует 3 в порядке кодировки символов. Тем не менее, функция в этом ответе вернется,["33", "111"]
потому что число33
меньше, чем число111
."33" > "111" === true
и33 > 111 === false
. Работает как задумано.Вы также можете использовать новый
Intl.Collator().compare
, согласно MDN, он более эффективен при сортировке массивов. Недостатком является то, что он не поддерживается старыми браузерами. MDN заявляет, что он вообще не поддерживается в Safari. Нужно проверить это, так как в нем говорится, чтоIntl.Collator
поддерживается.источник
Если вы хотите гарантировать один и тот же порядок независимо от порядка элементов во входном массиве, вот стабильная сортировка:
источник
Нормализовать регистр в
.sort()
с.toLowerCase()
.источник
Вы также можете использовать оператор Elvis:
дает:
Метод localeCompare, вероятно, хорошо, хотя ...
Примечание. Оператор Элвиса - это краткая форма «троичный оператор», если не всегда, обычно с присваиванием.
Если вы посмотрите на?: Sideway, это будет похоже на Элвиса ...
т.е. вместо:
ты можешь использовать:
т.е. когда y истинно, тогда возвращают 1 (для присваивания x), иначе возвращают 2 (для присваивания x).
источник
x = y ? y : z
, вы можете сделатьx = y ?: z
. Javascript не имеет фактического оператора Элвиса, но вы можете использоватьx = y || z
аналогичным образом.Другие ответы предполагают, что массив содержит строки. Мой метод лучше, потому что он будет работать, даже если массив содержит null, undefined или другие нестандартные значения.
null
Будет отсортирован между «Нульк» и «nulm». Но последний всегдаundefined
будет отсортирован.источник
(''+notdefined) === "undefined"
так что это будет сортировать до "Z"Array.prototype.sort
: | потому что часть about(''+notdefined) === "undefined"
действительно true ... что означает, что если вы перевернете -1 и 1 в функции сортировки, чтобы изменить порядок, неопределенное все равно будет сортироваться до конца. Это также необходимо учитывать при использовании функции сравнения вне контекста сортировки по массиву (как я это делал, когда натолкнулся на этот вопрос).Array.prototype.sort
определение - еще пара комментариев. Во-первых, нет необходимости(''+a)
- ECMAScript требует вызоваtoString()
элементов перед передачей их в compareFn. Во-вторых, тот факт, чтоignoreCase
возвращается1
при сравнении одинаковых (в том числе равных, но для случая) строк, означает, что спецификация не определяет результат, если есть повторяющиеся значения (вероятно, будет хорошо только при некоторых ненужных перестановках, я думаю).undefined
это особый случай, который для любого x x <undefined и x> undefined имеет значение false . Этоundefined
всегда последнее, является побочным продуктом реализации sort. Я пытался изменить ('' + a) на просто a, но это не удалось. я получаюTypeError: a.toUpperCase is not a function
. По-видимомуtoString
, не вызывается до вызова CompareFn.undefined
сравнения Fn никогда не называетсяВерсия ES6:
["Foo", "bar"].sort((a, b) => a.localeCompare(b, 'en', { sensitivity: 'base' }))
Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
источник
В поддержку принятого ответа я хотел бы добавить, что приведенная ниже функция, по-видимому, изменяет значения в исходном массиве для сортировки, так что она не только сортирует нижний регистр, но и значения верхнего регистра также изменяются на нижний регистр. Это проблема для меня, потому что хотя я хочу видеть Мэри рядом с Мэри, я не хочу, чтобы регистр первого значения Мэри был изменен на нижний регистр.
В моих экспериментах следующая функция из принятого ответа сортирует правильно, но не меняет значения.
источник
Это может помочь, если вы пытались понять:
http://jsfiddle.net/ianjamieson/wmxn2ram/1/
источник
В приведенной выше функции, если мы просто сравниваем в нижнем регистре два значения a и b, мы не получим симпатичного результата.
Например, если массив [A, a, B, b, c, C, D, d, e, E] и мы используем вышеупомянутую функцию, у нас есть именно этот массив. Это ничего не изменило.
Чтобы получить результат [A, a, B, b, C, c, D, d, E, e], мы должны снова сравнить, когда два строчных значения равны:
источник
Я завернул верхний ответ в полизаполнение, чтобы я мог вызвать .sortIgnoreCase () для строковых массивов
источник
Оберните свои строки в
/ /i
. Это простой способ использовать регулярные выражения, чтобы игнорировать обсадную колоннуисточник