How to add numbers in array via a loop in AS3? - actionscript-3

var arr: Array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
I can add these numbers to an array separately like this but how do I add 1 to 50 at once instead of typing it all the way through?
for (var i:Number=1; i<=50;i++){
var arr:Array(i) = [i];
}
function randomize(a: * , b: * ): int {
return (Math.random() > .5) ? 1 : -1;
}
trace(arr.sort(randomize));
I am trying to implement something like this.
Thank you.

Pretty simple. You can address the Array's elements via square bracket notation. Works both ways:
// Assign 1 to 10-th element of Array A.
A[10] = 1;
// Output the 10-th element of A.
trace(A[10]);
Furthermore, you don't even need to allocate elements in advance, Flash Player will automatically adjust the length of the Array:
// Declare the Array variable.
var A:Array;
// Initialize the Array. You cannot work with Array before you initialize it.
A = new Array;
// Assign some random elements.
A[0] = 1;
A[3] = 2;
// This will create the following A = [1, null, null, 2]
So, your script is about right:
// Initialize the Array.
var arr:Array = new Array;
// Iterate from 1 to 50.
for (var i:int = 1; i <= 50; i++)
{
// Assign i as a value to the i-th element.
arr[i] = i;
}
Just keep in mind that Arrays are 0-based, so if you forget about index 0 it will remain unset (it will be null).

Related

how to select random objects to display on a fixed position in adobe flash

I am working on a flash project and I want to select random objects from a number of objects.
For example if I have 15 objects and I want to randomly select just 4 objects and display them on the stage at fixed position.
I have searched different forums and the problems discussed on different forums are about changing the random position of objects
Note that I don't want to randomize objects position on stage I want to select random objects from multiple objects
I have no idea how to do this.
Please help me if anyone can.
The best thing is to put those objects into array, and then get random element from it.
Here is a quick example:
var objects:Array = new Array[obj1, obj2, obj3, obj4, obj5];
var random:Object = objects.splice(int(Math.random() * objects.length), 1)[0];
Have in mind that these are predefined objects - you must populate the array by yourself. Another thing is that this splices the array, which means it removes items from it.
Good luck!
Similar to Andrey Popov's answer but step by step instead of one line:
//an array of symbols
var objects:Array = new Array(red,blue,green);
//Number you need
var needed:Number = 2;
for (var i:Number = 0;i< needed;i++){
var randomPos = int(Math.random()*objects.length);
//Insert fixed position here
objects[i].x = 0;
//remove object from array
objects.splice(i,1);
}
You need some algorithm to get unique N objects from the object pool. For example try this one:
function getItemsFrom(list:Array, count:uint):Array {
var result:Array = [];
var needed:uint = count;
var available:uint = list.length;
while (result.length < count) {
if (Math.random() < needed / available) {
result.push(list[available - 1]);
needed--;
}
available--;
}
return result;
}
//Simple test, and some results are: [16,9,7,5], [14,13,10,1], etc
var test:Array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
for(var i:uint = 0; i < 20; ++i){
trace(getItemsFrom(test, 4));
}
After you will get array of objects, place them where you want.
//Place items vertically at (5,5);
var startX:int = 5;
var startY:int = 5;
//Vertical padding between items
var paddingY:int = 10;
//Current Y position
var posY:int = startY;
//Ger 2 random unique items from the given collection "someListWithItems"
var itemsToPlace:Array = getItemsFrom(someListWithItems, 2);
var item:DisplayObject, i:uint, len:uint = itemsToPlace.length;
for (i; i < len; ++i) {
item = itemsToPlace[i];
item.x = startX;
item.y = posY;
//Offset current position on height of object, plus padding
posY += item.height + paddingY;
//Add item to the display list
addChild(item);
}

As3 - Script Error on Arrays

please inspect me coding:
function createRandomList():void
{
var newlist:Array = [0,1,2];
var curlist:Array = item[selectedlevel - 1] //selectedlevel = 1;
var normal:int = curlist[0];
var tempboo1:Boolean = false;
var tempboo2:Boolean = false;
var tempboo3:Boolean = false;
while (curlist[0] + curlist[1] + curlist[2] > 0)
{
if (Number(curlist[0]) == 0 && tempboo1 == false)
{
newlist.splice(newlist.indexOf(0), 1);
tempboo1 = true;
}
if (Number(curlist[1]) == 0 && tempboo2 == false)
{
newlist.splice(newlist.indexOf(1), 1);
tempboo2 = true;
}
if (Number(curlist[2]) == 0 && tempboo3 == false)
{
newlist.splice(newlist.indexOf(2), 1);
tempboo3 = true;
}
var temp:int = Math.floor(Math.random()*(newlist.length));
curlist[temp] -= 1;
generatedlist.push(Number(newlist[temp]));
trace(item);
}
while (normal > 0)
{
var temp2:int = Math.floor(Math.random() * 3) + 1;
generatednormal.push(Number(temp2));
normal--;
}
}
My item was [[5,0,0],[10,0,0]];
But after became [[0,0,0],[0,0,0]];
I just want to duplicate Array item to be a new variable curlist.
Every time it traces, returning item[0][0] decreasing 1, I only want to use curlist as a temp Array to calculate a new random Array based on item[0].
Ouput:
4,0,0,10,0,0
3,0,0,10,0,0
2,0,0,10,0,0
1,0,0,10,0,0
0,0,0,10,0,0
Is there any links between them, or is it my problem? Please help! If you need any more infoemation, please comment me!
Arrays are passed by reference, not value. That means when you modify an array through any property that points to it, the original array will be modified.
To make a duplicate, you can use .slice()
Returns a new array that consists of a range of elements from the original array, without modifying the original array. The returned array includes the startIndex element and all elements up to, but not including, the endIndex element.
If you don't pass any parameters, the new array is a duplicate (shallow clone) of the original array.
You can clone your arrays if you want to create a new reference.
function clone( source:Object ):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject( source );
myBA.position = 0;
return( myBA.readObject() );
}
var a:Array = [[0,0],[1,1]];
var b:Array = clone(a);
b[0] = [2,2];
trace(a)
trace(b)
Output
0,0,1,1
2,2,1,1
It works for any object, not only arrays.
More infos here : AS3 - Clone an object
var array : Array = [ 1, 2, 3];
var array2 : Array = array.concnt();
array[ 0 ] = 4;
trace( array );// 1, 2, 3
trace( array 2);// 4, 2 ,3
So use .concat() to duplicate an array with primitives. If you have an arrays with arrays. Duplicate the children arrays, and put them into an empty one. If you have children of children arrays and so forth, make something recursive.

passing random values from one array to another without repetitions

I have an array (say 'origA') which contains 20 values and also another array (say "itemA" with only 1 value in it. I need to push any 10 random values of "origA" into "itemA". But i cannot push a same value which is already pushed into "itemA".
How can we do this?
You can create a copy of origA and remove from it the items you add to itemA:
Non optimized version:
var origA:Array = [1, 2, 3, 4, 5, 6, 7];
var itemA:Array = [0];
var copyA:Array = origA.concat();
var N:int = 10;
var n:int = Math.min(N, copyA.length);
for (var i:int = 0; i < n; i++) {
// Get random value
var index:int = Math.floor(Math.random() * copyA.length);
var value:int = copyA[index];
// Remove the selected value from copyA
copyA.splice(index, 1);
// Add the selected value to itemA
itemA.push(value);
}
trace(itemA);
//0,1,7,2,6,4,3,5
Optimized version (no calls to length, indexOf, splice or push inside the loop):
var origA:Array = [1, 2, 3, 4, 5, 6, 7];
var itemA:Array = [0];
var copyA:Array = origA.concat();
var copyALength:int = copyA.length;
var itemALength:int = itemA.length;
var N:int = 10;
var n:int = Math.min(N, copyALength);
for (var i:int = 0; i < n; i++) {
// Get random value
var index:int = Math.floor(Math.random() * copyALength);
var value:int = copyA[index];
// Remove the selected value from copyA
copyA[index] = copyA[--copyALength];
// Add the selected value to itemA
itemA[itemALength++] = value;
}
trace(itemA);
//0,2,5,7,4,1,3,6
Edit1: If your original array has only a few items, use my first version or any other solution in the other answers. But if it may have thousands items or more, then I recommend you use my optimized version.
Edit:2 Here is the time taken to copy 1,000 randomly chosen items from an array containing 1,000,000 items:
All other versions: 2000ms
Optimized version: 12ms
Optimized version without cloning the original array: 1ms
// Define how many random numbers are required.
const REQUIRED:int = 10;
// Loop until either the original array runs out of numbers,
// or the destination array reaches the required length.
while(origA.length > 0 && itemA.length < REQUIRED)
{
// Decide on a random index and pull the value from there.
var i:int = Math.random() * origA.length;
var r:Number = origA[i];
// Add the value to the destination array if it does not exist yet.
if(itemA.indexOf(r) == -1)
{
itemA.push(r);
}
// Remove the value we looked at this iteration.
origA.splice(i, 1);
}
Here's a real short one. Remove random items from the original array until you reach MAX, then concat to the target Array:
const MAX:int = 10;
var orig:Array = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var target:Array = [];
var tmp:Array = [];
var i : int = -1;
var len : int = orig.length;
while (++i < MAX && len > 0) {
var index:int = int( Math.random()*len );
tmp[i] = orig[index];
orig[index] = orig[--len];
}
target = target.concat(tmp);
EDIT
Adopted #sch's way of removing items. It's his answer that should be accepted. I just kept this one for the while-loop.

Loop through array, set property of each element?

Okay, very simple: there is an array containing 3 objects. Each object has a unique property called "ID" with values of either 1, 2, or 3.
One of the objects gets deleted.
The objective now is to update the ID property of each object corresponding to the new array.length value.
So for example, the object with ID of 2 got deleted. The remaining objects in the array would each have ID values of 1 and 3 respectively.
So the objective is to loop through the array and update the ID properties to 1, and 2 (instead of 1 and 3).
So I guess the question is how to write a loop to update a common property of each element in an array. Thanks.
You can use a for-loop to go through the array, as in walkietokyo's answer, or you can use a method closure:
myArray.forEach ( function ( item:*, i:int, arr:Array) : void { item.ID = i; } );
or a while-loop:
var i:int = -1;
while (++i < myArray.length) myArray[i].ID = i;
for (var i:uint = 1; i <= myArray.length; i++) {
myArray[i].ID = i;
}
General info on loops:
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7fcf.html
var i:uint; // for speed keep out of the loop
var arrayLength = myArray.length // for speed keep out of the loop
for (i = 0; i < arrayLength; i++) {
myArray[i].ID = i;
}

Does method already exist in ActionScript to search array and return first index whose element is > some #?

Using ActionScript 3, suppose I have an array of numbers, lets say: 1, 2, 3, 4, 5. Is there a way to easily search this array and return the index corresponding to an element that is >= 2.5 (which would be, 3, in this case), for example? I'm implementing this with a while and for loop, and seems pretty wordy. Thought there might be a method for this already, but haven't stumbled upon it in:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#every()
Otherwise, what would be a simple way to achieve it?
In case it helps, I'll use this to implement a straight-forward linear interpolation math routine, assuming one doesn't already exist I'm not aware of.
I'm not aware of any firstIndexOf in ActionScript.
You could add it to an ArrayUtil class:
Given the array:
var array:Array = [ 1, 2, 3, 4, 5 ];
Pass it to the ArrayUtil function:
public static function firstIndexOf(array:Array, value:Number):int
{
for(var i:uint = 0; i < array.length; i++)
{
if(array[i] >= value)
return i;
}
// if not found, return -1
return -1;
}
var t:Array = [4,9,1,2,3,5,6];
function something(base:Number, array:Array):int
{
var t:Array = array.slice();
var h:Number = int.MAX_VALUE;
var i:int = -1;
while(t.length > 0)
{
var l:Number = t.pop();
if(l >= base)
{
if(h > l)
{
h = l;
i = t.length;
}
}
}
return i;
}
trace(something(2, t)); // at index [3]