ホームページ >ウェブフロントエンド >htmlチュートリアル >JavaScript学習メモ: 配列のランダムソート_html/css_WEB-ITnose
JavaScript には、配列項目の順序を変更するための sort() メソッドと reverse() メソッドが用意されています。しかし、多くの場合、これら 2 つの方法では、ポーカー ゲームのランダム シャッフルなど、実際のビジネスのニーズを満たすことができません。
この記事では、上記の例の効果を実現する方法と、配列のランダムな順序に関する関連知識を学びましょう。
配列のランダムソートに関する関連情報をインターネットで調べたところ、Math.random() を見つけました。ブラウザ コントローラを開き、次のように入力します:
Math.random()
JavaScript 乱数の概要については、記事「Math.random() 乱数についての 2 つまたは 3 つのこと」を参照してください。
この図から、Math.random() が 0 ~ 1 の間の乱数を取得していることがわかります。ご存知のとおり、sort() はパラメーターとして関数を呼び出すことができます。関数が値 -1 を返した場合、配列内の項目 a が項目 b よりも前にランク付けされていることを意味します。このようにして、Math.random() によってランダムに生成された数値を 0.5 と比較するランダム関数を作成できます。数値が 0.5 より大きい場合は -1 (a が b の前にランク付けされます) を返します。 return 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 配列をリセットする必要があります。
上記の 2 つに加えて、メソッド、@Traveller 記事「配列要素のランダムな並べ替えアルゴリズムの実装」が DIV.IO で共有されました。この記事では、配列項目をランダムに並べ替えるための 3 つの実装方法を説明します。
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) です。
は、有限集合
の順序を破壊するアルゴリズムです。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;};シャッフルアルゴリズムに関する詳細な資料
初心者が学習ノートを作成していますが、間違っているところがあれば専門家に指導してもらいたいです。誤解を招いてしまい申し訳ございません。
Da Mo