【问题标题】:Unexpected different results array.sort() Chrome / Edge意外的不同结果 array.sort() Chrome / Edge
【发布时间】:2018-02-09 19:28:51
【问题描述】:

使用sort 拥有这段 Javascript 代码:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

console.log(items.map(x=>x.name.toString()));

items.sort();

console.log(items.map(x=>x.name.toString()));

即使我们可以在both browsers are compatible 中看到,结果也不同:

谷歌浏览器 63

["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]
["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]

微软边缘 25

["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]
["Sharpe", "And", "The", "Magnetic", "Zeros", "Edward"]

知道是什么原因造成的或如何解决?

您可以在以下JSBin中测试此行为

【问题讨论】:

  • 您认为您实际上在此处对 by 进行了哪些排序?您不会认为您是按 name 属性排序的,对吧?您正在使用对象比较进行排序。
  • 你要找的是items.sort((a.b) => a.name.localeCompare(b.name))
  • @CBroe,按 nothing 排序。所以我希望得到像 Chrome 一样的结果。我使用“名称”只是为了显示结果。
  • 你不能按“无”排序,这甚至没有意义。引用自 MDN,“如果省略 [compareFunction],则数组按照每个字符的 Unicode 码位值,按照每个元素的字符串转换进行排序。” 你的元素在这里是对象,所以它们的字符串转换将为每个项目生成[object Object] - 因此您的每个项目都有相同的比较值开始,它们都不比另一个“更小”或“更大”。所以你得到什么结果取决于浏览器实际使用的排序算法是否是一个稳定的

标签: javascript google-chrome sorting cross-browser microsoft-edge


【解决方案1】:

知道是什么原因造成的

引用自 MDN:

如果[compareFunction is]省略,则数组按照每个字符的Unicode码位值排序,按照每个元素的字符串转换。

您的元素在这里是对象,因此它们的字符串转换将导致每个元素的字符串值[object Object] - 因此您的每个项目都有相同的比较值开始,它们都没有比另一个“小”或“大”。

所以你得到什么结果取决于浏览器实际使用的排序算法是否是稳定的。 (另请参阅此问题,What is stability in sorting algorithms and why is it important?

https://medium.com/@fsufitch/is-javascript-array-sort-stable-46b90822543f:

嗯,ES7 规范中没有任何地方说明排序是否需要稳定。事实上,它试图变得超级抽象,尽可能多地允许“实现定义”。这导致不同的 JS 引擎(跨不同的浏览器)采用不同的路径来实现此规范,从而导致排序稳定性行为不一致。

.

或者如何解决?

您需要实现自己的稳定排序算法。

但您还需要使用自行编写的比较函数来正确比较您的对象,因为正如现在所说,您只比较 [object Object][object Object] ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 2022-07-12
    • 1970-01-01
    • 2022-08-17
    • 2016-03-29
    • 2011-09-15
    • 2012-04-02
    相关资源
    最近更新 更多