为什么这种 Array.sort 行为在 Chrome 和 Node.js 中不同
Why is this Array.sort behaviour different in Chrome vs Node.js
问题
让我们制作一个基本列表并对其进行排序,以确保 2
始终排在列表的第一位。很简单吧?
[1, 2, 3].sort((a, b) => {
if (a === 2) return -1;
return 0;
});
Chrome 结果:✓
[2, 1, 3]
节点结果:X
[1, 2, 3]
为了在 Node 中获得这种行为,你可以 - 很奇怪 - 查看 b
参数并将其设置为 return 1 如果它是 2
:
[1, 2, 3].sort((a, b) => {
if (b === 2) return 1;
return 0;
});
使用这个实现你会得到相反的结果; Chrome 将为 [1, 2, 3],节点将为 [2, 1, 3]。
问题
您对这种行为有合理的解释吗?
我的排序功能在概念上有缺陷吗?如果是这样,你会如何编写这种排序行为?
Do you have a logical explaination for this behaviour?
浏览器使用不同的排序方法。因此,他们可能会以不同的顺序使用不同的参数调用提供的回调。如果你的排序函数不一致,排序就不稳定。这将导致错误的排序顺序(对于不同的输入数组也总是如此,因此您的排序永远不会真正起作用)。
If so, how would you write this sorting behaviour?
确保这两个条件适用于每个可能的输入:
1) 两个相等的元素不应被排序:
sort(a, a) === 0
2) 如果调用排序函数的顺序是倒序的,结果也是倒序的:
sort(a, b) - sort(b, a) === 0
在你的情况下,两者都没有填满:
sort(2, 2) // 1 -> wrong!
sort(2, 3) - sort(3, 2) // 1 -> wrong!
要写出稳定的排序,得看a
和 b
:
function(a, b) {
if(a === 2 && b === 2)
return 0;
if(a === 2)
return 1;
if(b === 2)
return -1;
return 0;
}
或者缩短:
(a, b) => (a === 2) - (b === 2)
问题
让我们制作一个基本列表并对其进行排序,以确保 2
始终排在列表的第一位。很简单吧?
[1, 2, 3].sort((a, b) => {
if (a === 2) return -1;
return 0;
});
Chrome 结果:✓
[2, 1, 3]
节点结果:X
[1, 2, 3]
为了在 Node 中获得这种行为,你可以 - 很奇怪 - 查看 b
参数并将其设置为 return 1 如果它是 2
:
[1, 2, 3].sort((a, b) => {
if (b === 2) return 1;
return 0;
});
使用这个实现你会得到相反的结果; Chrome 将为 [1, 2, 3],节点将为 [2, 1, 3]。
问题
您对这种行为有合理的解释吗? 我的排序功能在概念上有缺陷吗?如果是这样,你会如何编写这种排序行为?
Do you have a logical explaination for this behaviour?
浏览器使用不同的排序方法。因此,他们可能会以不同的顺序使用不同的参数调用提供的回调。如果你的排序函数不一致,排序就不稳定。这将导致错误的排序顺序(对于不同的输入数组也总是如此,因此您的排序永远不会真正起作用)。
If so, how would you write this sorting behaviour?
确保这两个条件适用于每个可能的输入:
1) 两个相等的元素不应被排序:
sort(a, a) === 0
2) 如果调用排序函数的顺序是倒序的,结果也是倒序的:
sort(a, b) - sort(b, a) === 0
在你的情况下,两者都没有填满:
sort(2, 2) // 1 -> wrong!
sort(2, 3) - sort(3, 2) // 1 -> wrong!
要写出稳定的排序,得看a
和 b
:
function(a, b) {
if(a === 2 && b === 2)
return 0;
if(a === 2)
return 1;
if(b === 2)
return -1;
return 0;
}
或者缩短:
(a, b) => (a === 2) - (b === 2)