当我在JavaScript中写下"Ł" > "Z"
,它返回true
。按Unicode顺序应该是false
。如何修复?我的网站正在使用UTF-8。
当我在JavaScript中写下"Ł" > "Z"
,它返回true
。按Unicode顺序应该是false
。如何修复?我的网站正在使用UTF-8。
Intl.Collator
或String.prototype.localeCompare
,这是由ECMAScript国际化API引入的:"Ł".localeCompare("Z", "pl"); // -1
new Intl.Collator("pl").compare("Ł","Z"); // -1
-1
表示 Ł
在字母表中排在 Z
之前,就像您想要的那样。请注意,这仅适用于最新版本的浏览器。"这里有一个法语字母表的例子,可以帮助您进行自定义排序:
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')
);
在alpha()
的第二个参数中添加1
或-1
以进行升序或降序排序。
在第三个参数中添加true
以进行区分大小写的排序。
你可能需要将数字和特殊字符添加到字母表中。
你可以使用localeCompare()
来构建自己的排序函数,根据MDC文章的说法,它应该能够正确地排序。
如果这种方法不起作用,这里有一个有趣的SO问题,其中OP使用字符串替换来构建“暴力”排序机制。
在那个问题中,OP还展示了如何为jQuery tablesorter插件构建自定义的textExtract
函数,用于区域设置感知排序-也值得一看。
编辑:作为一个非常奇特的想法 - 我完全不知道这是否可行,特别是由于性能的考虑 - 如果你已经在后端使用PHP/mySQL,我想提到发送一个Ajax查询到mySQL实例进行排序的可能性。 mySQL非常擅长排序区域设置感知数据,因为您可以使用例如ORDER BY xyz COLLATE utf8_polish_ci
,COLLATE utf8_german_ci
...的命令将排序操作强制为特定的排序规则。这些排序规则会同时解决所有排序问题。
localeCompare()
:http://blog.schmichael.com/2008/07/14/javascript-collation-fail/ - BalusClocaleCompare()
没有很好的感觉),我会像Tomalak在你提供的链接中所做的那样实现自定义的函数。 - BalusC对于未提及的字符,Mic的代码进行了改进:
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]");
你需要保留两个排序关键字符串。一个是用于主排序的,其中德语中的ä=a(主排序 a->a),法语中的é=e(主排序 e->e),而另一个是用于次要排序的,例如ä在a之后(将a转换为azzzz作为次要关键字)或者é在e之后(次要关键字e->ezzzz)。特别是在捷克语中,一些字母是字母的变体(如áéí…),而其他字母则在列表中占有其完整的权利(ABCČD…GHChI…RŘSŠT…)。此外,还需要考虑将二合字视为单个字母(例如主排序ch->hzzzz)。这不是一个简单的问题,但应该可以在JS中找到解决方案。
myArray.sort(new Intl.Collator('pl').compare);
- xandruvar 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"
L
之后吗?也就是说,..J,K,L,Ł,M,N,O..
? - BalusC