Javascript 基于另一个数组对JS数组进行排序的最快方法';s的价值观?
有一些类似的帖子,但我找不到任何能完全解决这个问题的。。。 我有两个成对值的数组:Javascript 基于另一个数组对JS数组进行排序的最快方法';s的价值观?,javascript,arrays,Javascript,Arrays,有一些类似的帖子,但我找不到任何能完全解决这个问题的。。。 我有两个成对值的数组: var A=[0.5, 0.6, 0.5, 0.7, 0.8, 0.1] var B=['a','b','c','d','e','f'] //note: a=0.5, b=0.6, c=0.5, d=0.7, etc 什么是对处理器最友好的方法来对数组进行排序,从而使数组A按数字升序排列,并保持数据结构?我想内置数组。sort(函数)最快,但我对语法没有信心。对于任何排序算法,在算法时间和其他约束(通常是内存)
var A=[0.5, 0.6, 0.5, 0.7, 0.8, 0.1]
var B=['a','b','c','d','e','f']
//note: a=0.5, b=0.6, c=0.5, d=0.7, etc
什么是对处理器最友好的方法来对数组进行排序,从而使数组A按数字升序排列,并保持数据结构?我想内置数组。sort(函数)最快,但我对语法没有信心。对于任何排序算法,在算法时间和其他约束(通常是内存)之间都有一个折衷。您可能希望了解和,两种常见且非常快速的排序算法。您需要做一些小的修改,因为您实际上是在对两个数组进行排序,第一个数组是要排序的数据源,但是这种更改是微不足道的
编辑:注意,array.sort()不适用于您,因为您希望arr1中的更改反映在arr2中。您必须编写自己的排序函数有点粗糙,但它可以工作
var A = [0.5, 0.6, 0.5, 0.7, 0.8, 0.1];
var B = ['a', 'b', 'c', 'd', 'e', 'f'];
var all = [];
for (var i = 0; i < B.length; i++) {
all.push({ 'A': A[i], 'B': B[i] });
}
all.sort(function(a, b) {
return a.A - b.A;
});
A = [];
B = [];
for (var i = 0; i < all.length; i++) {
A.push(all[i].A);
B.push(all[i].B);
}
console.log(A, B);
基本上,我们是在一个新数组中创建一个在a
和B
之间有明确联系的对象,然后sort()
然后我返回并重建两个阵列的原始阵列
更新
在评论中提出了一个很好的观点。他建议将AAAAB值放入[0.5,'A']
等数组中,而不是生成{A:0.5,B:'A'}
这样的对象
这应该更快,不过如果需要调试all
数组,它的可读性会稍差一些。如果您遇到性能问题,请分析这两种方法并选择最快的方法。如果可能,您最好实际创建一个数据结构。这样,在维护结构的同时,可以基于一个属性对$A[]
进行排序。我没有做过任何速度测试或其他什么,但可能像
A[0]['label']='a';
A[0]['value']=0.5;
A[1]['label']='b';
A[1]['value']=0.6;
A[2]['label']='c';
A[2]['value']=0.5;
A[3]['label']='d';
A[3]['value']=0.7;
A[4]['label']='e';
A[4]['value']=0.8;
A[5]['label']='f';
A[5]['value']=0.1;
如果您有一个带有元组的数组而不是两个数组,那么会简单得多。因为这样您就可以使用内置的Array.sort()
在这之后,你可以写:
arr.sort(function(x,y) { return x.a - y.a });
Array.prototype.swap=函数(a,b)
{
var tmp=此[a];
这个[a]=这个[b];
这个[b]=tmp;
}
函数分区(数组、数组2、开始、结束、轴)
{
var piv=数组[pivot];
数组.交换(pivot,end-1);
阵列2.交换(枢轴,末端1);
var存储=开始;
var ix;
对于(ix=begin;ix在
排序是最简单的方法
var a1, b1, A= [0.5, 0.6, 0.5, 0.7, 0.8, 0.1],
B= ['a', 'b', 'c', 'd', 'e', 'f'],
ab= A.map(function(itm, i){ return [itm, i]; });
ab.sort(function(a, b){ return a[0]-b[0]; });
B= ab.map(function(itm){
A.push(itm[0]);
return B[itm[1]];
});
A= A.splice(B.length);
alert(A+'\n'+B)
/* returned value: (String)
0.1, 0.5, 0.5, 0.6, 0.7, 0.8
f, a, c, b, d, e
*/
我注意到上面所有的解决方案都使用了映射。另一种节省内存的方法是创建一个索引数组,根据a对索引进行排序,然后根据索引重建a和B
var A=[0.5, 0.6, 0.5, 0.7, 0.8, 0.1];
var B=['a','b','c','d','e','f'];
var indices = A.map(function(elem, index){return index;}); //an array of indices
indices.sort(function (a,b) {return A[a] - A[b];});
//print out the results
for (var i = 0; i < A.length; i++)
document.body.innerHTML += 'A: ' + A[indices[i]] + ', B: ' + B[indices[i]] + '<br>';
我不认为冒泡排序是一种非常快的算法:-)可能对于非常小或几乎排序的列表,但即使如此,我还是更喜欢插入排序。没错,尽管它在速度上缺乏,但在简单性上弥补了它的不足。事实上,它很快,不是运行,而是实现:-P。我想知道纯javascript快速排序实现与本机内置版本相比有多好(我认为这是一个mergesort实现)。实际上,ECMA规范声明排序算法是“实现定义的”,所以这取决于javascript引擎的设计。也就是说,我很难相信javascript排序算法的执行速度比任何现有的本机实现都快。我感谢您使用google,但如果您要发布一篇文章,您应该归功于原始源代码。此外,您的更改也可以通过在递归调用的开始和结束中插入unnecessary@jordancpaul我同意,我本可以相信这是有礼貌的,但我发布这篇文章时很匆忙。我已经更新了帖子。你也可以使用“zip”函数从两个数组中创建一个元组数组——很容易实现,在O(n)中工作.使用两个项目数组([A[i],B[i]]
)填充arr
数组取而代之的对象可能会更快、内存效率更高。这不是和对其中一个数组进行排序一样吗?我在你的答案中看不出另一个数组有什么用处。请注意,我在JSFIDLE上运行了你的代码,另一个数组也被排序了。尽管你应该在输出中包含这一点all
使用all.push([A[i],B[i]])
然后使用A[0]-B[0]
进行排序可能会快一些,并且使用更少的内存,特别是当A
和B
变大时。@Már我同意你的意见,但我将保留我的答案,并提供一个注释:)这里有一个更新的JSFIDLE测试,它使用数组和更少的函数调用:嘿,Netscape调用了,它想要回它的文档.layers
对象。很好!这在速度方面如何比较?我需要每10毫秒运行一次这个函数扫描使用map重组:A=A.map(函数(v,I,A){返回A[index[I]})
。实际上,将map应用到索引index.map(函数(i){return B[i];});
。使用此函数,您可以将整个内容链接到var BSorted=a.map(函数(e,i){return i;})。排序(函数(a,B){return a[a]-a[B];})。map(函数(e){return B[e];});
Array.prototype.swap=function(a, b)
{
var tmp=this[a];
this[a]=this[b];
this[b]=tmp;
}
function partition(array, array2, begin, end, pivot)
{
var piv=array[pivot];
array.swap(pivot, end-1);
array2.swap(pivot, end-1);
var store=begin;
var ix;
for(ix=begin; ix<end-1; ++ix) {
if(array[ix]<=piv) {
array.swap(store, ix);
array2.swap(store, ix);
++store;
}
}
array.swap(end-1, store);
array2.swap(end-1, store);
return store;
}
function qsort(array, array2, begin, end)
{
if(end-1>begin) {
var pivot=begin+Math.floor(Math.random()*(end-begin));
pivot=partition(array, array2, begin, end, pivot);
qsort(array, array2, begin, pivot);
qsort(array, array2, pivot+1, end);
}
}
var a1, b1, A= [0.5, 0.6, 0.5, 0.7, 0.8, 0.1],
B= ['a', 'b', 'c', 'd', 'e', 'f'],
ab= A.map(function(itm, i){ return [itm, i]; });
ab.sort(function(a, b){ return a[0]-b[0]; });
B= ab.map(function(itm){
A.push(itm[0]);
return B[itm[1]];
});
A= A.splice(B.length);
alert(A+'\n'+B)
/* returned value: (String)
0.1, 0.5, 0.5, 0.6, 0.7, 0.8
f, a, c, b, d, e
*/
var A=[0.5, 0.6, 0.5, 0.7, 0.8, 0.1];
var B=['a','b','c','d','e','f'];
var indices = A.map(function(elem, index){return index;}); //an array of indices
indices.sort(function (a,b) {return A[a] - A[b];});
//print out the results
for (var i = 0; i < A.length; i++)
document.body.innerHTML += 'A: ' + A[indices[i]] + ', B: ' + B[indices[i]] + '<br>';
var BSorted = A.map(function(e,i){return i;})
.sort(function(a,b){return A[a] - A[b];})
.map(function(e){return B[e];});