actionscript 3を使用して配列をランダム化するにはどうすればよいですか?
8 に答える
Array.sort() 関数を使用した短いバージョンがあります。
var arr : Array = [0,1,2,3,4,5,6,7,8,9];
function randomize ( a : *, b : * ) : int {
return ( Math.random() > .5 ) ? 1 : -1;
}
trace( arr.sort( randomize ) );
「十分な」ランダム性が得られない場合は、2回ソートできます:)
編集 - 行ごとの説明:
Array
クラスメソッドの場合、などsort()
の並べ替えオプションだけArray.CASEINSENSITIVE, Array.DESCENDING
でなく、2 つのパラメーター (配列から比較する 2 つの要素) を受け入れる独自のカスタム比較関数参照 (コールバック) も渡すことができます。AS3 ドキュメントから:
比較関数は、比較するために 2 つの引数を取る必要があります。要素 A と B を指定すると、compareFunction の結果は、負、0、または正の値になる可能性があります。
- 負の戻り値は、ソートされた順序で A が B の前に表示されることを指定します。
- 戻り値 0 は、A と B の並べ替え順序が同じであることを示します。
- 正の戻り値は、ソートされた順序で A が B の後に表示されることを指定します。
注: 比較関数のパラメーターは型指定されている場合があり (配列が型指定されている場合)、任意の名前を付けることができます。
function compareElements ( elementA : SomeClass, elementB : SomeClass ) : int;
このメソッドは、配列要素を特殊なプロパティでソートする必要がある場合に非常に便利です。ランダム化の場合、配列要素をcompareFunction
ランダムに返す-1, 0
か1
、またはそれらの場所 (インデックス) を切り替えるようにします。私は、(私の主観的で数学的にテストされていない意見では) より良いランダム化は、メソッドが と のみ-1
を返す場合であることを発見しました1
。また、カスタム比較関数を使用した並べ替え関数は要素を順番に比較しないため、特殊なケースでは、ランダム化の結果が予想と異なる場合があることに注意してください。
必要に応じて、アレイを所定の位置にランダム化することもできる、より良い方法があります。これにより、元のアレイのコピーを1つ以上作成することはできません。
package
{
import flash.display.Sprite;
public class RandomizeArrayExample extends Sprite
{
public function RandomizeArrayExample()
{
super();
testDistribution();
}
private function testDistribution():void
{
var hash:Object = { };
var tester:Array = [1, 2, 3, 4];
var key:String;
for (var i:int; i < 1e5; i++)
{
randomize(tester);
key = tester.join("");
if (key in hash) hash[key]++;
else hash[key] = 1;
}
for (var p:String in hash) trace(p, "=>", hash[p]);
}
private function randomize(array:Array):Array
{
var temp:Object;
var tempOffset:int;
for (var i:int = array.length - 1; i >= 0; i--)
{
tempOffset = Math.random() * i;
temp = array[i];
array[i] = array[tempOffset];
array[tempOffset] = temp;
}
return array;
}
}
}
これはより簡単な機能です。多次元配列でも動作します
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
var mn=Math.floor(Math.random()*array.length)
newArray[newArray.length]=array[mn]
array.splice(mn,1)
}
return newArray;
}
これはとても役に立ちました。あなたにも役立つことを願っています。
// Array to Randomize
var firstArray:Array = ["One","Two","Three","Four","Five","six","seven","eight","nine","ten"];
trace(firstArray); // Prints in order
var newArray:Array = new Array();
function randomizeArray(array:Array):Array
{
var newArray:Array = new Array();
while (array.length > 0)
{
newArray.push(array.splice(Math.floor(Math.random()*array.length), 1));
}
return newArray;
}
var randomArray:Array = randomizeArray(firstArray);
trace(randomArray); // Prints out randomized :)
多くのソース配列をターゲット配列にランダムに挿入したいという別の要件がありました。Rytis のように、私は配列の forEach、map、および sort 関数の大ファンです。
var randomInsert:Function = function callback(item:*, index:int, array:Vector.<MyItem>):void
{
var j:Number = Math.floor(Math.random() * targetArray.length);
targetArray.splice(j,0,item);
}
targetArray = new Vector.<MyItem>();
sourceArray1.forEach(randomInsert, this);
sourceArray2.forEach(randomInsert, this);
配列をシャッフルする必要がある場合 (要素を繰り返すことはできません)。この関数を使用できます:
/**
* Shuffles array into new array with no repeating elements. Simple swap algorithm is used.
*/
public function shuffleArray(original:Array):Array
{
// How many swaps we will do
// Increase this number for better results (more shuffled array, but slower performance)
const runs:int = original.length * 3;
var shuffled:Array = new Array(original.length);
var i:int;
var a:int;
var b:int;
var temp:Object;
// Copy original array to shuffled
for(i=0; i<shuffled.length; i++){
shuffled[i] = original[i];
}
// Run random swap cycle 'runs' times
for(i=0; i<runs; i++){
// There is a chance that array element will swap with itself,
// and there is always small probability it will make your shuffle
// results not that good, hence try to experiment with
// different runs count as stated above
a = Math.floor(Math.random() * original.length);
b = Math.floor(Math.random() * original.length);
// Swap messages
temp = shuffled[a];
shuffled[a] = shuffled[b];
shuffled[b] = temp;
}
return shuffled;
}
使用法:
var testArray:Array = ["Water", "Fire", "Air", "Earth"];
trace(shuffleArray(testArray).concat());
これは、メモリーゲーム用に36枚のカードの配列をランダム化する方法です
const QUANT_CARTAS: int = 36;
//get the 36 numbers into the array
for (var i: int = 0; i < QUANT_CARTAS; i++)
{
cartas.push(i);
}
//shuffles them =)
for (var moeda: int = QUANT_CARTAS - 1; moeda > 0; moeda--)
{
var pos: int = Math.floor(Math.random() * moeda);
var carta: int = cartas[moeda];
cartas[moeda] = cartas[pos];
cartas[pos] = carta;
}
// and add them using the random order...
for (i = 0; i < QUANT_CARTAS; i++)
{
var novaCarta: Carta = new Carta();
novaCarta.tipoCarta = cartas[i];
etcetcetc.............
}