JavaScript Array#sort()函数使用哪种算法?我知道它可以采取各种各样的参数和函数来执行不同类型的排序,我只是对vanilla排序使用哪种算法感兴趣.
我有一个非常简单的JSON对象,如下所示:
{
"people":[
{
"f_name":"john",
"l_name":"doe",
"sequence":"0",
"title":"president",
"url":"google.com",
"color":"333333"
},
{
"f_name":"michael",
"l_name":"goodyear",
"sequence":"0",
"title":"general manager",
"url":"google.com",
"color":"333333"
}
]
}
Run Code Online (Sandbox Code Playgroud)
现在,这是从我的服务器端代码返回的,我运行jQuery.each以形成必要的html并输出结果.
现在我正在做的是向包含我的排序信息的服务器发送一个AJAX调用...例如"Title DESC"并重新运行SQL查询以返回新的结果集.但我想避免这种情况,并使用jQuery对生成的JSON进行排序,以防止往返服务器和多个数据库访问.
我怎样才能使用jQuery实现这一目标?
假设我有一个Javascript数组,如下所示:
var test = ['b', 'c', 'd', 'a'];
Run Code Online (Sandbox Code Playgroud)
我想对数组进行排序.显然,我可以这样做来排序数组:
test.sort(); //Now test is ['a', 'b', 'c', 'd']
Run Code Online (Sandbox Code Playgroud)
但我真正想要的是一个索引数组,指示排序元素相对于原始元素的位置.我不太清楚怎么说这个,所以也许这就是为什么我无法弄清楚如何去做.
如果这样的方法被称为sortIndices(),那么我想要的是:
var indices = test.sortIndices();
//At this point, I want indices to be [3, 0, 1, 2].
Run Code Online (Sandbox Code Playgroud)
'a'位于第3位,'b'位于0,'c'位于1,'d'是原始阵列中的2.因此,[3,0,1,2].
一种解决方案是对数组的副本进行排序,然后循环遍历排序的数组并找到原始数组中每个元素的位置.但是,这感觉很笨拙.
是否有现有方法可以满足我的需求?如果没有,您将如何编写一个执行此操作的方法?
假设我有这个数组:
var array = [
{ name: "border-color", value: "#CCCCCC" },
{ name: "color", value: "#FFFFFF" },
{ name: "background-color", value: "rgb(0, 0, 0)" },
{ name: "background-color", value: "rgba(0, 0, 0, .5)" }
];
Run Code Online (Sandbox Code Playgroud)
此函数按名称对数组进行排序:
array.sort(function(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
});
Run Code Online (Sandbox Code Playgroud)
排序不一定稳定(即,比较相等的元素不一定保持原始顺序).
因此,排序后,名称=背景颜色的两个项目可以按任何顺序出现,即:
[
{ name: "background-color", value: "rgb(0, 0, 0)" },
{ name: "background-color", value: "rgba(0, 0, 0, .5)" },
...
]
Run Code Online (Sandbox Code Playgroud)
要么 …
在JavaScript(有些适用于其他地方),你不知道你的代码在哪个目标实现上运行,是否有一种方法可以检测基础排序算法(of Array.sort)是否稳定,只知道它遵循规范?
我可以在webkit (1) (2)中找到2个测试,但这些测试有多可靠?(这可以通过PCP进行检查吗?)我正在寻找一种在数学上合理的解决方案.
这是一个棘手的问题,因为更高级的排序算法可以根据源数组的长度(如Timsort)更改子算法.我一直很困惑,因为我所运行的每一项测试都表明Google Chrome的稳定性,但我见过的所有文档都说它不稳定(来源会告诉你原因).
(通常情况下,我使用此策略使我的排序稳定;它有一个小但有时显着的性能影响)
各种实现中的排序源代码:这是我在无数个小时修复JS与跨浏览器兼容(主要是IE)后一直在思考的问题:为什么 Javascript 在浏览器中不一致?
我的意思是,为什么JS不能像Java和Flash一样好看?相反,我们必须采用像jQuery这样的框架.不要误会我的意思,他们让我的生活更轻松 - 但为什么他们甚至首先存在?
这有历史原因吗?推出浏览器的公司是否只运送自己的JS引擎?使标准化如此困难的政治是什么?
(注意:我知道问题的很大一部分是与DOM相关的,但问题仍然存在).
在我的应用程序中,我需要对大型数组(100,000到1,000,000之间)的随机数进行排序.
我一直在使用内置的array.sort(comparisonFunction)compareFunction看起来像这样:
function comparisonFunction(a,b) {
return a-b;
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但我读过(例如,Native JavaScript排序执行比实现的mergesort和quicksort慢),有更快的选项,特别是如果您的要求满足特定条件:
那么 - 在这种情况下,最快(或足够接近)的排序算法是什么?
并且,是否存在规范(或至少相对理想)的JavaScript实现?
[UPDATE]
Yikes ...发布后30秒内两张投票!因此,快速澄清 - 在相关问题中,OP需要稳定的排序.因为我没有 - 我想知道这是否会改变答案(也就是说,如果您事先知道您的数据不会被预先排序,并且您不需要稳定的排序,也许可以使用更快的排序选项).
也许答案是"不",但这就是我要问的原因.
[更新#2]
这是quicksort的一个实现,除非我犯了一个错误 - 轻松地击败本机排序函数:
function comparisonFunction(a, b) {
return a - b;
}
function quickSort(arr, leftPos, rightPos, arrLength) {
let initialLeftPos = leftPos;
let initialRightPos = rightPos;
let direction = true;
let pivot = rightPos;
while ((leftPos - rightPos) < 0) {
if (direction) {
if (arr[pivot] < arr[leftPos]) …Run Code Online (Sandbox Code Playgroud)根据MDN规范,Javascript的sort()函数是"不稳定的"(不维护相同元素的输入顺序).
具有讽刺意味的是,似乎Firefox目前还没有实现这一点 - 但Chrome似乎也是如此.
这给我留下了一些问题.我有一组要排序的元素 - 一旦排序我想将它们标记为'已排序',以便随后的排序尝试不会浪费大量时间发现它们已经排序(如果有任何变化,我可以取消标记) .
问题是,我的解决方案是在我的比较函数中返回'0',但这意味着我只是为每个元素返回'等价'并且它们可以(并且将)被洗牌.
这表明了问题(在这里小提琴)
<head>
<script>
var firsttime=true;
function test() {
debugger;
var elements = document.getElementById('test').children;
var sortMe = [];
for (var i=0; i<elements.length; i++)
sortMe.push(elements[i]);
sortMe.sort(function(a, b) {
if (firsttime) {
if (a.innerText < b.innerText) return -1;
else if (a.innerText > b.innerText) return 1;
else return 0;
} else {
return 0;
}
});
var parent = document.getElementById('test');
parent.innerHTML = "";
for(var i = 0, l = sortMe.length; i …Run Code Online (Sandbox Code Playgroud) 我尝试对我的对象数组进行排序:
目的:
interface IFriend {
_id: string;
name: string;
surname: string;
avatar: string;
online: boolean;
}
Run Code Online (Sandbox Code Playgroud)
我想按顺序进行 - 在线,姓氏,姓名。我试过这个:
friendsCopy
.sort((a: IFriend, b: IFriend) =>
a.online === b.online ? 0 : a.online ? -1 : 1
)
.sort((a: IFriend, b: IFriend) => a.surname.localeCompare(b.surname, "pl"))
.sort((a: IFriend, b: IFriend) => a.name.localeCompare(b.name, "pl"));
Run Code Online (Sandbox Code Playgroud)
但效果不佳