Как сравнить строки Unicode в Javascript? - PullRequest
38 голосов
/ 02 сентября 2010

Когда я пишу в JavaScript "Ł" > "Z", возвращается true.В порядке Юникода это должно быть, конечно, false.Как это исправить?Мой сайт использует UTF-8.

Ответы [ 6 ]

32 голосов
/ 13 мая 2014

Вы можете использовать Intl.Collator или String.prototype.localeCompare, представленный Интернационализация API ECMAScript :

"Ł".localeCompare("Z", "pl");              // -1
new Intl.Collator("pl").compare("Ł","Z");  // -1

-1означает, что Ł предшествует Z, как вы хотите.

Обратите внимание, что он работает только в последних браузерах.

19 голосов
/ 03 сентября 2010

Вот пример французского алфавита, который может помочь вам для пользовательской сортировки:

var alpha = function(alphabet, dir, caseSensitive){
  return function(a, b){
    var pos = 0,
      min = Math.min(a.length, b.length);
    dir = dir || 1;
    caseSensitive = caseSensitive || false;
    if(!caseSensitive){
      a = a.toLowerCase();
      b = b.toLowerCase();
    }
    while(a.charAt(pos) === b.charAt(pos) && pos < min){ pos++; }
    return alphabet.indexOf(a.charAt(pos)) > alphabet.indexOf(b.charAt(pos)) ?
      dir:-dir;
  };
};

Чтобы использовать его в массиве строк a:

a.sort(
  alpha('ABCDEFGHIJKLMNOPQRSTUVWXYZaàâäbcçdeéèêëfghiïîjklmnñoôöpqrstuûüvwxyÿz')
);

Добавьте 1 или -1 в качестве второго параметра alpha() для сортировки по возрастанию или по убыванию.
Добавьте true в качестве 3-го параметра для сортировки с учетом регистра.

Возможно, вам потребуется добавить цифры и специальные символы в список алфавита

13 голосов
/ 03 сентября 2010

Вы можете создать свою собственную функцию сортировки, используя localeCompare(), которая - по крайней мере, согласно статье MDC по теме - должна сортировать вещи правильно.

Если это не такНе получается, вот интересный вопрос SO , где OP использует замену строк для создания механизма сортировки "грубой силы".

Также в этом вопросе OP показывает, какbuild пользовательская textExtract функция для плагина jQuery tablesorter, который выполняет сортировку с учетом локали - возможно, также стоит посмотреть.

Редактировать: Как полностью далекоИдея - я понятия не имею, возможно ли это вообще, особенно из-за проблем с производительностью - если вы все равно работаете с PHP / mySQL на сервере, я хотел бы упомянуть возможность отправки запроса Ajax на mySQLНапример, чтобы это было отсортировано там.mySQL отлично справляется с сортировкой данных, учитывающих локали, потому что вы можете принудительно сортировать операции в определенном порядке сортировки, используя, например, ORDER BY xyz COLLATE utf8_polish_ci, COLLATE utf8_german_ci .... эти параметры сортировки позаботятся обо всех проблемах сортировки сразу.

9 голосов
/ 03 сентября 2010

Улучшен код микрофона для не упомянутых символов:

var alpha = function(alphabet, dir, caseSensitive){
  dir = dir || 1;
  function compareLetters(a, b) {
    var ia = alphabet.indexOf(a);
    var ib = alphabet.indexOf(b);
    if(ia === -1 || ib === -1) {
      if(ib !== -1)
        return a > 'a';
      if(ia !== -1)
        return 'a' > b;
      return a > b;
    }
    return ia > ib;
  }
  return function(a, b){
    var pos = 0;
    var min = Math.min(a.length, b.length);
    caseSensitive = caseSensitive || false;
    if(!caseSensitive){
      a = a.toLowerCase();
      b = b.toLowerCase();
    }
    while(a.charAt(pos) === b.charAt(pos) && pos < min){ pos++; }
    return compareLetters(a.charAt(pos), b.charAt(pos)) ? dir:-dir;
  };
};

function assert(bCondition, sErrorMessage) {
      if (!bCondition) {
          throw new Error(sErrorMessage);
      }
}

assert(alpha("bac")("a", "b") === 1, "b is first than a");
assert(alpha("abc")("ac", "a") === 1, "shorter string is first than longer string");
assert(alpha("abc")("1abc", "0abc") === 1, "non-mentioned chars are compared as normal");
assert(alpha("abc")("0abc", "1abc") === -1, "non-mentioned chars are compared as normal [2]");
assert(alpha("abc")("0abc", "bbc") === -1, "non-mentioned chars are compared with mentioned chars in special way");
assert(alpha("abc")("zabc", "abc") === 1, "non-mentioned chars are compared with mentioned chars in special way [2]");
0 голосов
/ 23 января 2019

Вы должны сохранить две строки сортировки ключей.Один для первичного порядка, где немецкий ä = a (первичный a-> a) и французский é = e (первичный ключ сортировки e-> e) и один для вторичного порядка, где ä следует после (перевод a-> azzzz во вторичныйключ) или é идет после e (вторичный ключ e-> ezzzz).Особенно в чешском языке некоторые буквы являются вариациями буквы (áéí…), в то время как другие стоят в своем полном праве в списке (ABCČD… GHChI… RŘSŠT…).Плюс проблема в рассмотрении орграфов отдельными буквами (первичные ch-> hzzzz).Нет тривиальной проблемы, и в JS должно быть решение.

0 голосов
/ 29 ноября 2013

Забавно, я должен подумать об этой проблеме и закончить поиск здесь, потому что мне пришло в голову, что я могу использовать свой собственный модуль javascript.Я написал модуль для генерации чистого URL, поэтому мне нужно транслировать входную строку ... (http://pid.github.io/speakingurl/)

var mySlug = require('speakingurl').createSlug({
    maintainCase: true,
    separator: " "
});

var input = "Schöner Titel läßt grüßen!? Bel été !";
var result;

slug = mySlug(input);
console.log(result); // Output: "Schoener Titel laesst gruessen bel ete"

Теперь вы можете сортировать с этими результатами. Вы можете сохранить исходный титр ex.в поле "title" и поле для сортировки в "title_sort" с результатом mySlug.

...