JSON.stringify()
将转义一些字符(如双引号字符、反斜杠字符或任何控制字符),因此这些字符不太可能正确排序。
此外,由于空格的 ascii 代码低于双引号,因此如果您的两个数组以"abcd "
and开头"abcd"
,它们将无法在 JSON 中正确排序。 "abcd "
应该在 之后"abcd"
,但是空格的 ascii 值比双引号低,所以它会在之前排序。值末尾的感叹号也是如此。
如果根据您的评论,您还希望它适用于数字等非数组成员,则字符串比较不适用于比较具有不同位数的两个数字,因为1000
不小于2
,但"1000"
小于"2"
。
另外,我建议您.localeCompare()
在第二个算法中使用比较两个字符串,因为它已经具有内置的正、负或零结果。
如果您所有的值都是字符串或者它们通过 正确排序.toString()
,您可以这样使用.localeCompare()
:
data.sort(function(a, b) {
var comp, i;
for (i = 0; i < Math.min(a.length, b.length); i++) {
if ((comp = a[i].localeCompare(b[i])) !== 0) return comp;
}
return (a.length > b.length) - (a.length < b.length);
});
.localeCompare
还有一些选项可用于区分大小写、忽略标点符号、如何处理重音字符以及其他一些选项。
根据您的评论和MDN,与 Collator 对象(仅在某些浏览器中可用)相比,您可以获得更好的性能。根据文档(我自己只尝试过一次此代码),它的工作原理如下:
var collater = new Intl.Collator();
data.sort(function(a, b) {
var comp, i;
for (i = 0; i < Math.min(a.length, b.length); i++) {
if ((comp = collater.compare(a[i], b[i])) !== 0) return comp;
}
return (a.length > b.length) - (a.length < b.length);
});
大概必须有一些初始化或开销可以通过这种方式完成一次。也许他们建立了直接查找排序表。
但是浏览器对 Collator 对象的支持很少(IE 11、Chrome、没有 Firefox、没有 Safari),所以除非你在浏览器插件中使用它,所以代码只针对一个浏览器,你必须分支不管它是否被支持并且有两个实现。
PS 如果你有相当数量的外部数组元素,因此多次调用排序回调,它会执行得非常糟糕。你至少可以让它JSON.stringify()
每次只打两次电话,而不是四次。