javascript - 这两种数组排序算法是否会对任何输入产生不同的输出?

标签 javascript arrays algorithm sorting

其中数据是以下格式的元数组,

[
  [
        "qux doo",
        "adsf",
        "abcd",
        "zzzz",
        "898jwe9"
  ],
  [
        "abcd",
        "xxrwu",
        "urnr",
        "pupupu",
        "sdsdsd"
  ]
]

对于不同的输入数据值,以下两种算法是否会产生不同的结果?

data.sort(function(a,b){
  return (JSON.stringify(a) < JSON.stringify(b)) - (JSON.stringify(a) > JSON.stringify(b));
});

data.sort(function(a, b) {
    for (var i = 0; i < Math.min(a.length, b.length); i++) {
        if (a[i] < b[i]) return -1;
        if (a[i] > b[i]) return 1;
    } 
    return (a.length > b.length) - (a.length < b.length); 
});

最佳答案

JSON.stringify() 将转义某些字符(如双引号字符、反斜杠字符或任何控制字符),因此这些字符不太可能正确排序。

此外,由于空格的 ascii 码比双引号低,如果您的两个数组以 "abcd ""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 还有一些选项可用于区分大小写、忽略标点符号、如何处理重音字符,以及其他一些。


根据您的评论和 per MDN ,与 Collat​​or 对象(仅在某些浏览器中可用)相比,您可以获得更好的性能。根据文档(我自己只尝试过一次这段代码),它是这样工作的:

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); 
});

大概必须有一些初始化或开销可以通过这种方式只完成一次。也许他们构建了直接查找排序表。

但是浏览器对 Collat​​or 对象的支持很少(IE 11、Chrome、没有 Firefox、没有 Safari)所以除非你在浏览器插件中使用它,所以代码只特定于一个浏览器,你会有分支是否支持它并有两个实现。


附言如果你有相当数量的外部数组元素,因此多次调用排序回调,它的性能会非常糟糕。您至少可以让它每次只执行两次 JSON.stringify() 调用,而不是四次。

关于javascript - 这两种数组排序算法是否会对任何输入产生不同的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19992253/

相关文章:

javascript - RoR : destroy. js.erb 未与销毁操作一起运行

javascript - 如何找到循环中对象数组的总和?

javascript - 由于奇怪的原因数组更改值

python - Numpy 如何推断数组的 dtype

string - 字符串 "chunk"是否有名称说明?

javascript - 如何在 Algolia 的 instantsearch 中实现使用每个用户的 firebase uid 进行搜索?

javascript - 动态时钟中 div 或文本的 CSS 样式

javascript - 如何捕获 DataTables Angular 5 的下一个/上一个分页按钮上的单击事件

algorithm - 具有黄色和黑色边缘的最短路径

algorithm - OpenCV:如何检测视频中是否有快速移动的物体?