搜尋
首頁web前端html教學JavaScript学习笔记:数组随机排序_html/css_WEB-ITnose

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

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

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

Math.random()

有关于JavaScript随机数相关介绍,可以阅读《 Math.random()随机数的二三事 》一文。

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

function randomSort(a, b) {    return Math.random() > 0.5 ? -1 : 1;}

看个示例:

var arr = [1,2,3,4,5,6,7,8,9];arr.sort(randomSort);

这样一来,就可以实现文章开头的示例效果:

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

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

function randomSort(arr, newArr) {    // 如果原数组arr的length值等于1时,原数组只有一个值,其键值为0    // 同时将这个值push到新数组newArr中    if(arr.length == 1) {        newArr.push(arr[0]);        return newArr; // 相当于递归退出    }    // 在原数组length基础上取出一个随机数    var random = Math.ceil(Math.random() * arr.length) - 1;    // 将原数组中的随机一个值push到新数组newArr中    newArr.push(arr[random]);    // 对应删除原数组arr的对应数组项    arr.splice(random,1);    return randomSort(arr, newArr);}

如此一来,我们就可以这样使用:

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

输出结果:

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

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

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

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

Array.prototype.shuffle = function(n) {    var len = this.length ,        num = n ? Math.min(n,len) : len,        arr = this.slice(0);    arr.sort(function(a,b){        return Math.random()-0.5;    });    return arr.slice(0,num-1);}

随机交换数组内的元素

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

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

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

洗牌算法

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

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

原理

  • 定义一个数组( 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 方法

function random(min, max) {    if (max == null) {      max = min;      min = 0;    }    return min + Math.floor(Math.random() * (max - min + 1));};function shuffle(arr) {  var length = arr.length,      shuffled = Array(length);  for (var index = 0, rand; index < length; index++) {      rand = random(0, index);      if (rand !== index) shuffled[index] = shuffled[rand];      shuffled[rand] = arr[index];    }    return shuffled;}

实际运用:

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

Chrome输出的结果如下:

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

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

function shuffle(arr) {    var i,         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;    }    return arr;};

有关于洗牌算法扩展阅读

  • Fisher–Yates shuffle
  • Shuffling an Array in JavaScript
  • Fisher–Yates Shuffle
  • 如何测试洗牌程序
  • Fisher-Yates-shuffle洗牌算法
  • How to randomize (shuffle) a JavaScript array?

总结

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

初学者学习笔记,如有不对,还希望高手指点。如有造成误解,还希望多多谅解。

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《 图解CSS3:核心技术与案例实战 》。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
HTML:結構,CSS:樣式,JavaScript:行為HTML:結構,CSS:樣式,JavaScript:行為Apr 18, 2025 am 12:09 AM

HTML、CSS和JavaScript在Web開發中的作用分別是:1.HTML定義網頁結構,2.CSS控製網頁樣式,3.JavaScript添加動態行為。它們共同構建了現代網站的框架、美觀和交互性。

HTML的未來:網絡設計的發展和趨勢HTML的未來:網絡設計的發展和趨勢Apr 17, 2025 am 12:12 AM

HTML的未來充滿了無限可能。 1)新功能和標準將包括更多的語義化標籤和WebComponents的普及。 2)網頁設計趨勢將繼續向響應式和無障礙設計發展。 3)性能優化將通過響應式圖片加載和延遲加載技術提升用戶體驗。

HTML與CSS vs. JavaScript:比較概述HTML與CSS vs. JavaScript:比較概述Apr 16, 2025 am 12:04 AM

HTML、CSS和JavaScript在網頁開發中的角色分別是:HTML負責內容結構,CSS負責樣式,JavaScript負責動態行為。 1.HTML通過標籤定義網頁結構和內容,確保語義化。 2.CSS通過選擇器和屬性控製網頁樣式,使其美觀易讀。 3.JavaScript通過腳本控製網頁行為,實現動態和交互功能。

HTML:是編程語言還是其他?HTML:是編程語言還是其他?Apr 15, 2025 am 12:13 AM

HTMLISNOTAPROGRAMMENGUAGE; ITISAMARKUMARKUPLAGUAGE.1)htmlStructures andFormatSwebContentusingtags.2)itworkswithcsssforstylingandjavascript for Interactivity,增強WebevebDevelopment。

HTML:建立網頁的結構HTML:建立網頁的結構Apr 14, 2025 am 12:14 AM

HTML是構建網頁結構的基石。 1.HTML定義內容結構和語義,使用、、等標籤。 2.提供語義化標記,如、、等,提升SEO效果。 3.通過標籤實現用戶交互,需注意表單驗證。 4.使用、等高級元素結合JavaScript實現動態效果。 5.常見錯誤包括標籤未閉合和屬性值未加引號,需使用驗證工具。 6.優化策略包括減少HTTP請求、壓縮HTML、使用語義化標籤等。

從文本到網站:HTML的力量從文本到網站:HTML的力量Apr 13, 2025 am 12:07 AM

HTML是一種用於構建網頁的語言,通過標籤和屬性定義網頁結構和內容。 1)HTML通過標籤組織文檔結構,如、。 2)瀏覽器解析HTML構建DOM並渲染網頁。 3)HTML5的新特性如、、增強了多媒體功能。 4)常見錯誤包括標籤未閉合和屬性值未加引號。 5)優化建議包括使用語義化標籤和減少文件大小。

了解HTML,CSS和JavaScript:初學者指南了解HTML,CSS和JavaScript:初學者指南Apr 12, 2025 am 12:02 AM

WebDevelovermentReliesonHtml,CSS和JavaScript:1)HTMLStructuresContent,2)CSSStyleSIT和3)JavaScriptAddSstractivity,形成thebasisofmodernWebemodernWebExexperiences。

HTML的角色:構建Web內容HTML的角色:構建Web內容Apr 11, 2025 am 12:12 AM

HTML的作用是通過標籤和屬性定義網頁的結構和內容。 1.HTML通過到、等標籤組織內容,使其易於閱讀和理解。 2.使用語義化標籤如、等增強可訪問性和SEO。 3.優化HTML代碼可以提高網頁加載速度和用戶體驗。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具