根据我的研究和谷歌搜索,Javascript似乎缺乏对区域设置感知排序和字符串比较的支持。有localeCompare()
,但它已经reported of browser specific differencies并且不可能明确设置使用哪个区域设置(操作系统区域设置并不总是所需的区域设置)。有一些intentions to add collation support inside ECMAScript,但在它之前,我们是独立的。根据浏览器结果的一致性,我们可能会永远保持自己:(。
我有以下代码,它按字母顺序排列数组。考虑到速度,这些想法来自https://stackoverflow.com/a/11598969/1691517,我提高了速度。
在这个例子中,单词数组有13个成员,sort-function被调用34次。我想替换单词数组中的一些字母(你不必知道取代了什么,因为这不是这个问题的重点)。如果我在sort-function(以return function(a, b)
开头的那个)中进行这些替换,则代码效率很低,因为每个数组成员都会进行多次替换。当然我可以在这个闭包之外进行这些替换,我的意思是在行words.sort(sortbyalphabet_timo);
之前,但这不是我想要的。
问题1:是否可以修改“PREPARATION STARTS”和“PREPARATION ENDS”之间的单词数组,以便sort函数使用修改后的单词数组?
问题2:是否可以向闭包输入参数,以便PREPARATION STARTS和PREPARATION ENDS之间的代码可以使用它们?我试过这个没有成功:
var caseinsensitive = true;
words.sort( sortbyalphabet_timo(caseinsensitive) );
最后是代码示例,准备运行示例位于http://jsfiddle.net/3E7wb/:
var sortbyalphabet_timo = (function() {
// PREPARATION STARTS
var i, alphabet = "-0123456789AaÀàÁáÂâÃãÄäBbCcÇçDdEeÈèÉéÊêËëFfGgHhIiÌìÍíÎîÏïJjKkLlMmNnÑñOoÒòÓóÔôÕõÖöPpQqRrSsTtUuÙùÚúÛûÜüVvWwXxYyÝýŸÿZz",
index = {};
i = alphabet.length;
while (i--) index[alphabet.charCodeAt(i)] = i;
// PREPARATION ENDS
return function(a, b) {
var i, len, diff;
if (typeof a === "string" && typeof b === "string") {
(a.length > b.length) ? len = a.length : len = b.length;
for (i = 0; i < len; i++) {
diff = index[a.charCodeAt(i)] - index[b.charCodeAt(i)];
if (diff !== 0) {
return diff;
}
}
// sort the shorter first
return a.length - b.length;
} else {
return 0;
}
};
})();
var words = ['tauschen', '66', '55', '33', 'täuschen', 'andern', 'ändern', 'Ast', 'Äste', 'dosen', 'dösen', 'Donaudam-0', 'Donaudam-1'];
$('#orig').html(words.toString());
words.sort(sortbyalphabet_timo);
$('#sorted').html(words.toString());`
答案 0 :(得分:2)
是否可以在“PREPARATION STARTS”和“PREPARATION ENDS”行之间修改单词数组,以便sort函数使用修改后的单词数组?
不,不是真的。您无权访问数组本身,您的函数仅构建在数组上调用.sort
时稍后使用的比较函数。如果你需要改变数组,你需要编写一个函数来获取它作为参数;例如,您可以在Array.prototype
上添加方法。它看起来像
function mysort(arr) {
// Preparation
// declaration of compare function
// OR execution of closure to get the compare function
arr.sort(comparefn);
return arr;
}
是否可以向闭包输入参数,以便PREPARATION STARTS和PREPARATION ENDS之间的代码可以使用它们?
是的,当然 - 这是使用闭包的原因:-)但是,您不能将sortbyalphabet_timo(caseinsensitive)
与当前代码一起使用。您拥有的闭包会立即被调用(称为IIFE)并返回比较函数,您将在演示中将其传递给sort。
如果希望sortbyalphabet_timo
成为闭包而不是结果,则必须删除它后面的括号。您也可以在那里使用参数,这些参数可以在整个闭包范围内访问(包括比较函数):
var sortbyalphabet_timo_closure = function(caseinsensitive) {
// Preparation, potentially using the arguments
// Declaration of compare function, potentially using the arguments
return comparefn;
}
// then use
words.sort(sortbyalphabet_timo_closure(true));
目前,您正在这样做:
var sortbyalphabet_timo_closure = function(/*having no arguments*/) {
// Preparation, potentially using the arguments
// Declaration of compare function, potentially using the arguments
return comparefn;
}
var sortbyalphabet_timo = sortbyalphabet_timo_closure();
// then use
words.sort(sortbyalphabet_timo);
...如果您需要多次排序,它只会缓存执行闭包的结果。