Showing posts with label Array. Show all posts
Showing posts with label Array. Show all posts

Friday, July 17, 2009

Generate unique random numbers within a range

Following on from a previous post on how to generate a list of unique random numbers, this similar function will allow you to do the same...but within a predefined range of numbers:

function randListFromRange(firstNo:Number, lastNo:Number, num:Number, shuffled:Boolean):Array {
var tempArray:Array = [];
for (i = firstNo - 1; i < lastNo && num > 0; ++i) {
if (Math.floor(Math.random() * (lastNo - i)) < num) {
tempArray.push(i + 1);
num--;
}
}
if (shuffled) {
tempArray.sort(function () {
return Math.floor(Math.random() * 2) ? true : false;
});
}
return (tempArray);
}

To use this function, just provide the first and last numbers in your range, and the number of items you wish to generate from that list. For example, you might want to create an array of 7 unique random numbers that lie between 36 and 83:

// to generate an array of 7 unique sequential numbers
// between, and including, 36 and 83
var myArr:Array = randListFromRange(36, 83, 7);
trace(myArr);

As previously, the function still allows for the list of random numbers to be shuffled:

// to generate an array of 7 unique shuffled numbers
// between, and including, 36 and 83
var myArr:Array = randListFromRange(36, 83, 7, true);
trace(myArr);

Two points to note:
1. If your first number is greater than your last number, then no random numbers will be generated. For example:

var myArr:Array = randListFromRange(20, 10, 5);
trace(myArr); // outputs nothing

2. If the specified range is smaller than the desired number, the function will return every integer within that range. For example:

// attempt to generate an array of 10 unique shuffled numbers
// between, and including, 10 and 15
var myArr:Array = randListFromRange(10, 15, 10);
trace(myArr); // outputs 10, 11, 12, 13, 14, 15

Sunday, March 1, 2009

Generating a list of unique random numbers

Here's a useful function for generating a list of N random numbers from a larger list M:

function randList(max:Number, num:Number, shuffled:Boolean):Array {
var tempArray:Array = [];
for (i = 0; i < max && num > 0; ++i) {
if (Math.floor(Math.random() * (max - i)) < num) {
tempArray.push(i + 1);
num--;
}
}
if (shuffled) {
tempArray.sort(function () {
return Math.floor(Math.random() * 2) ? true : false;
});
}
return (tempArray);
}

Just provide the maximum number (M) in your list and the number of items (N) you wish to generate from that list:

// to generate an array of 10 unique sequential numbers
// between 1 and 10
var myArr:Array = randList(10, 10);
trace(myArr);
// to generate an array of 5 unique sequential numbers
// between 1 and 100
var myArr:Array = randList(100, 5);
trace(myArr);

Finally, the function also allows for the list of N random numbers to be shuffled:

// to generate an array of 10 unique shuffled numbers
// between 1 and 10
var myArr:Array = randList(10, 10, true);
trace(myArr);
// to generate an array of 5 unique shuffled numbers
// between 1 and 100
var myArr:Array = randList(100, 5, true);
trace(myArr);

Thursday, July 31, 2008

Sorting a numbered list

One task that's quite common is the sorting of data in an array. But there are some pitfalls to bear in mind, particularly when it comes to sorting numbers.

For example, take the following simple list and apply a sort:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort();
trace(list);
// outputs [1, 10, 15, 2, 21, 5]

Yikes...that didn't go exactly according to plan! So what happened? By default, the Array.sort() method converts numbers to strings before they're sorted, and then it sorts them according to their Unicode value.

Fortunately, Flash provides an option to perform a numeric sort on an array containing numbers:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort(Array.NUMERIC);
trace(list);
// outputs [1, 2, 5, 10, 15, 21]

Flash treats the contents of the array as numeric values and performs a correct sort. Which is fine, but what if the contents of the array are already stored as strings?


var list:Array = ["5", "10", "2", "21", "1", "15"];
list.sort(Array.NUMERIC);
trace(list);
// // outputs [1, 10, 15, 2, 21, 5]

Uh-oh, it looks like we're back to square one again!

Fortunately, it's easy to create a function that can correct this default behaviour by comparing each individual element in the array:


function compare(a, b) {
return a - b;
}

var list:Array = ["5", "10", "2", "21", "1", "15"];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

The same function works with numbers too:


var list:Array = [5, 10, 2, 21, 1, 15];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

And it will even perform a correct numerical sort with a mix of numbers and strings:


var list:Array = [5, "10", 2, "21", "1", 15];
list.sort(compare);
trace (list);
// outputs [1, 2, 5, 10, 15, 21]

If you want to reverse the order of your sort, the function handles that too; just swap the arguments around before they're returned:


function reverse(a, b) {
return b - a;
}