日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

js调整数组某些元素到指定位置顺序_如何将一个 JavaScript 数组打乱顺序?

發(fā)布時間:2025/4/16 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js调整数组某些元素到指定位置顺序_如何将一个 JavaScript 数组打乱顺序? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1)首先,毫無疑問: @顧軼靈 軼靈大佬給出的Fisher–Yates shuffle 洗牌算法是最完美亂序的算法/方法之一了,正解無疑。

2)同時,很多答案提到了:

[12,4,16,3].sort(function() {

return .5 - Math.random();

});

這樣使用 sort 的方法。某些場景下,這樣的方法可以使用。但是這不是真正意義上的完全亂序,一些需求中(比如抽獎)這樣的寫法會出大問題。

3) 也有答案提到了優(yōu)秀的 lodash 庫 _.shuffle 方法。這也是正解,事實上翻開 lodash 源碼相關部分,這個方法正是采用了 Fisher–Yates shuffle 洗牌算法。感興趣的同學可以進行參閱。

到此,這個回答應該已經有了相對完善的解釋。但是最為優(yōu)秀的碼農,還是可以繼續(xù)“追根問底”。正好現(xiàn)在有點時間,我來針對這幾點,稍微解釋并拓展一下。

1) 為什么借助 sort 方法不是真正意義上的完全亂序?

先證明不完全性。為此實現(xiàn)一個腳本,我對

var letters = ['A','B','C','D','E','F','G','H','I','J'];

letters 這樣一個數組使用 array.sort 方法進行了 10000 次亂序處理,并把亂序的每一次結果可視化輸出。每個元素(ABCD...)出現(xiàn)的位置次數進行記錄:

不管點擊按鈕幾次,你都會發(fā)現(xiàn)整體亂序之后的結果絕對不是“完全隨機”。

比如 A 元素大概率出現(xiàn)在數組的頭部,J 元素大概率出現(xiàn)在數組的尾部,所有元素大概率停留在自己初始位置。

究其原因,在Chrome v8引擎源碼中,可以清晰看到,v8 在處理 sort 方法時,使用了插入排序和快排兩種方案。當目標數組長度小于10時,使用插入排序;反之,使用快排。

其實不管用什么排序方法,大多數排序算法的時間復雜度介于 O(n) 到 O(n2) 之間,元素之間的比較次數通常情況下要遠小于 n(n-1)/2,也就意味著有一些元素之間根本就沒機會相比較(也就沒有了隨機交換的可能),這些 sort 隨機排序的算法自然也不能真正隨機。

通俗的說,其實我們使用 array.sort 進行亂序,理想的方案或者說純亂序的方案是:數組中每兩個元素都要進行比較,這個比較有 50% 的交換位置概率。如此一來,總共比較次數一定為 n(n-1)。

而在 sort 排序算法中,大多數情況都不會滿足這樣的條件。因而當然不是完全隨機的結果了。

2) Fisher–Yates shuffle 洗牌算法是什么,為什么滿足需求?

這里,我們簡單借助圖形來理解,非常簡單直觀。你接下來就會明白為什么這是理論上的完全亂序(圖片來源于網絡)。

首先我們有一個已經排好序的數組:

Step1:

第一步需要做的就是,從數組末尾開始,選取最后一個元素。

在數組一共 9 個位置中,隨機產生一個位置,該位置元素與最后一個元素進行交換。

Step2:

上一步中,我們已經把數組末尾元素進行隨機置換。

接下來,對數組倒數第二個元素動手。在除去已經排好的最后一個元素位置以外的8個位置中,隨機產生一個位置,該位置元素與倒數第二個元素進行交換。

Step3:

理解了前兩部,接下來就是依次進行,如此簡單。

最后,我們實現(xiàn)代碼:

Array.prototype.shuffle = function() {

var array = this;

var m = array.length,

t, i;

while (m) {

i = Math.floor(Math.random() * m--);

t = array[m];

array[m] = array[i];

array[i] = t;

}

return array;

}

當然這種代碼不是純凈的,這就屬于另一層面的問題了。純函數與非純,開發(fā)者可以依照自己的開發(fā)模式和習慣,自行考慮。

以上,前三段進行了總結。后面大篇幅進行了解釋。讀者可以根據需要進行閱讀。很多內容都是拾人牙慧,探究精神對于程序員來說還是很必要的。

總結

以上是生活随笔為你收集整理的js调整数组某些元素到指定位置顺序_如何将一个 JavaScript 数组打乱顺序?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。