J**aScript学习笔记之数组随机排序

时间:2016.04.19 发布人:yang2565985

J**aScript学习笔记之数组随机排序

已解决问题

谷歌yang2565985用户在2016.04.19提交了关于“人物J**aScript学习笔记之数组随机排序”的提问,欢迎大家涌跃发表自己的观点。目前共有1个回答,最后更新于2025-02-27T09:37:28。希望大家能够帮助她。

详细问题描述及疑问:期待您的答案,谢了,下次有事儿别忘了找我 !

希望以下的回答,能够帮助你。

第1个回答

用户名:6rr2t9t7fg  

推荐阅读:J**aS换斯危整雨cript学习笔记之数组求和方法

J**aScript学习笔记之数组的增、删、改、查

J**aScript中提供了sort()和镇久氧交reverse()方法对数组项重新排序。但很多时候这两个方法无法满足我们实际业务的需求,比如说扑克牌游戏中的随机洗牌。

在这篇文章一起来学习如何完成上面这个示例的效果,以及一些有关于数组随机排序的相关知识。

在网上查了一下有关于数组随机排序的相关**,都看到了Math.random()的身影。打开浏览器控制器,输入:

Math.random()

从图中可以看出Math.random()得到的是0~1之间的随机数。众所周知,sort()可以调用一个函数做为参数,如果这个函数返回的值为-1表示数组中的a项排在b项前。如此一来,可以写问帮其倒接利德作尔吗一个随机函数,让Math.random()力你随机出来的数与0.5做为一个比较,如果大于.5就返回-1(a排在b前面),反之返回1(b排在a前面):

functionrandomSort(a,b){returnMath.random()>0.5?-1:1;}

看个示例:

vararr=[1,2,3,4,5,6,7,8,9];arr.sort(rando伟让烟论营致划mSort);

这样一来茶甚富地社输物态含来,就可以实现文章开头冷判诉势与杆电的示例效果:

虽然前面的方法实现了数组的随机排序,但总感觉每个元素被派到新守据三跟济神务型数组的位置不是随机的。就如前面的示例,数组arr中值为1的元场半慢学点素,它的原先键值为0,随机排序后,1的键值要求上为0-8的几率是一样的。航掌前天见次然后在这里是递减的,原因是sort()方法是依次比较的。

针对这种现象,我们可以使用下面这种递归的方法来处理:

functionrandomSort(arr,newArr){//如果原数组arr的length值等于1时,原数组只有一个值,其键值为0//同时将这个值p蛋ush到新数组newArr中if(arr.length==1){newArr.push(arr[0]);returnnewArr;//相当于递归退出}//在原数组length基础上取出一个随机数varrandom=Math.ceil(Math.random()*arr.lengt次氢h)-1;//将原数组中者的随机一个值push到新数组newArr中newArr.push(arr[random]);//对应删除原数组arr的对应数组项arr.splice(random,1);returnrandomSo首rt(arr,n倍治攻亲益向ewArr);}

如此委欢督架众延怎画基省一来,我们就可以这样使用:

for(vari=0;i<10排陆;i++){vararr=[1,2,3,4,5,6,7,8,9];varnewArr=[];randomSort(arr,newArr);console.log(newArr);}

输出结果:

执行randomSort(arr,newArr)函数之后,原数组arr就清空了。

如果使用这种方法来做文章开头洗牌的示例,就要在resetPic()函数中重置pukePic数组:

除了上面的两种方法之外,@Tr**eller在***.IO分享了一篇《数组元素随机化排序算法实现》,这篇文章提供了三种数组项随机排序的实现方法:

使用数组sort方法对数组元素随机排序

Array.prototype.shuffle=function(n){varlen=this.length,**m=n?Math.min(n,len):len,arr=this.slice(0);arr.sort(function(a,b){returnMath.random()-0.5;});returnarr.slice(0,**m-1);}

随机交换数组内的元素

lib={}lib.range=function(min,max){returnmin+Math.floor(Math.random()*(max-min+1));}Array.prototype.shuffle=function(n){varlen=this.length,**m=n?Math.min(n,len):len,arr=this.slice(0),temp,index;for(vari=0;i<len;i++){index=lib.range(i,len-1);temp=arr[i];arr[i]=arr[index];arr[index]=temp;}returnarr.slice(0,**m);}

随机从原数组抽取一个元素,加入到新数组

lib={}lib.range=function(min,max){returnmin+Math.floor(Math.random()*(max-min+1));}Array.prototype.shuffle=function(n){varlen=this.length,**m=n?Math.min(n,len):len,arr=this.slice(0),result=[],index;for(vari=0;i<**m;i++){index=lib.range(0,len-1-i);//或者result.concat(arr.splice(index,1))result.push(arr.splice(index,1)[0]);}returnresult}

洗牌算法

数组随机排序其基本原理是洗牌算法(Fisher–Yatesshuffle):

是一种将有限集合的顺序打乱的一种算法

原理

定义一个数组(shuffled),长度(length)是原数组(arr)长度
取0到index(初始0)随机值rand,shuffled[index]=shuffled[rand],shuffled[rand]=arr[index]
index++;重复第二步,直到index=length-1
就是shuffled从0到length-1的赋值过程,并且新加入的值是arr[index],shuffled[index]的值是已赋值的元素中随机值shuffled[rand],因为这样会有两个重复的值,所以shuffled[rand]就等于新加入的值arr[index]

underscore.js中的shuffle方法

functionrandom(min,max){if(max==**ll){max=min;min=0;}returnmin+Math.floor(Math.random()*(max-min+1));};functionshuffle(arr){varlength=arr.length,shuffled=Array(length);for(varindex=0,rand;index<length;index++){rand=random(0,index);if(rand!==index)shuffled[index]=shuffled[rand];shuffled[rand]=arr[index];}returnshuffled;}

实际运用:

vararr=[1,2,3,4,5,6,7,8,9];for(vari=0;i<10;i++){console.log(shuffle(arr));}

Chrome输出的结果如下:

同样的,使用洗牌算法来完成文章最开头的示例:

还有更简单易理解的写法:

functionshuffle(arr){vari,j,temp;for(i=arr.length-1;i>0;i--){j=Math.floor(Math.random()*(i+1));temp=arr[i];arr[i]=arr[j];arr[j]=temp;}returnarr;};

总结

这篇文章主要总结和收集了有关于数组随机排序我相关**。当然在坊间实现类似功能的方法还有很多种,此处只是收集和整理了这些,如果你有更好的方法,欢迎在评论中与我们一起分享。

以上内容是小编给大家介绍的J**aScript学习笔记之数组随机排序的相关介绍,希望对大家有所帮助!