I have an input field and a list of numbers (10,43,98,10,45,23,10). I want to convert it to an Array, so I can use this array for multiple functions. Please help point me in the right direction.
var a:Array = Array[];
a.push(_numInput.text);//this is my input field name
//trace(a);
var l:Number = 0;
for(var i:uint=0; i< a.length; i++)
{
var t1:Number = l += a[i];
var t2:Number = a.length;
var t3:Number = t1 / t2;
}
trace(t3);
//when i trace the _numInput.text the number show up but i can not use them.
Use split(); to convert string like this to an array.
var a:Array = _numInput.text.split(",");
If you have comma separated numbers in your text field then following is a simplest way to get an array,
var str = "10,43,98,10,45,23,10";
function convertTextFieldStringToArray(s:String):Array
{
var a = s.split(",");
return a;
}
trace(convertTextFieldStringToArray(str));
Spliting a string will just create an array of strings
So what you need to do is then convert that array to an array of int
public function mapIt(obj:Object, index:int, arr:Array):int {
// validation might be a good idea here since this is user imputed text.
return int(obj) // convert to int
}
// your input string
var str:String = "10,43,98,10,45,23,10";
// convert string to array of strings
var arrayOfStrings:Array = str.split(",")
trace( typeof arrayOfStrings[0])// verify first element is a string
trace( arrayOfStrings[0] + arrayOfStrings[0]) // verify string concatination
var arrayOfInt:Array = arrayOfStrings.map(mapIt) // map each element
trace( typeof arrayOfInt[0]) // verify first element is an int
trace( arrayOfInt[0] + arrayOfInt[0]) // verify numbers are correctly added
You need to Cast the String to an Integer!!
a.push(int(_numInput.text));
Edit:Ups, seems i didn't quite understand the question pre-edit
Related
I am getting closer to finding a solution for the errors being generated when running the code below.
I have three boxes on the stage. The goal is to load one random item from the array without any one item being duplicated in more than one of the three boxes.
Yasuyuki Uno has been very helpful. We are currently trying to solve the following:
Code:
var animalArray: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7, animal8, animal9, animal10];
var randArr: Array = [];
var rand: int;
// Get random value for 3 times.
for(var i:int=0,len:int=animalArray.length;i<3;i++,len--){
rand = Math.floor( Math.random() * len); // Generate random integer between 0 and len-1.
randArr.push(animalArray.splice(rand,1)); // Delete a value from original array and add that value to new array.
}
box1.addChild(randArr[0]);
box2.addChild(randArr[1]);
box3.addChild(randArr[2]);
Error Message: Incorrect number of arguments. Expected no more than 0
Any help would be greatly appreciated. Thnx!
Assuming that animal1, animal2, etc are linkage IDs in your library, they are class references so they need to be instantiated using the new operator.
There are a few other non-critical issues with your code that made it hard to understand from my point of view:
Using animal1 instead of Animal1 and so on for class names. Uncapitalized names look like properties or functions, not classes.
Using Array instead of Vector. Vectors give you better errors; had you been using Vectors from the start your problem would be obvious.
Example:
var animalTypes:Vector.<Class> = new <Class>[Animal1, Animal2, Animal3, Animal4, Animal5, Animal6, Animal7, Animal8, Animal9, Animal10];
var randomAnimals:Vector.<DisplayObject> = new <DisplayObject>[];
// Get random value for 3 times.
for (var i:int = 0; i < 3; i++){
// Generate random integer between 0 and length-1.
var randomIndex:int = Math.random() * animalTypes.length;
// Remove a class from original vector.
var randomAnimalType:Class = animalTypes.splice(randomIndex, 1)[0];
// Create an instance of the animal class.
var randomAnimal:DisplayObject = new randomAnimalType();
// Add the instance to the random vector.
randomAnimals.push(randomAnimal);
}
box1.addChild(randomAnimals[0]);
box2.addChild(randomAnimals[1]);
box3.addChild(randomAnimals[2]);
As you check length of animalArray in for expression, it's no need to change variable len.
Also if you want to fill with 3 random items new array, you need to use this code:
const arr: Array = [animal1, animal2, animal3, animal4, animal5, animal6, animal7];
const genArr: Array = [];
var len: int = arr.length;
var n: int = 3;
while(n--) {
const randIndex: int = Math.floor(Math.random()*len); // get random index
genArr.push(arr.splice(randIndex, 1)[0]); // splice returns array, so we need first and exist item
len--; // decrement length as optimized solution of no-read length of array each cycle
}
trace(genArr);
I am an absolute newbie to ActionScript 3 and I need to create a function that searches an array of alphabets for a specific letter and return its index. I already found the indexOf which is perfect. But I need this search to be not case sensitive. Like if my array is this:
Array("a","B","c")
if I am looking for "A" the index returned would be 0.
Is there some predefined function for this?
I don't think there is a predefined function for this.
You can write your own, though. Use a for-loop and iterate through the array, using String.toLowerCase() to alter both the array value and the check value temporarily for checking.
Actually... asking you to write your own is asking you to shoot yourself in the foot for something like this. Create a class ArrayUtils, stuff this function in it.
/**
* Searches through an array for a case-insensitive string match.
* Attempts to imitate Array.indexOf where it can.
* #param arr The array to search through
* #param searchingFor The string to search for
* #param fromIndex Optional, an index to start searching at.
* #returns The index of the array that a match was found at (zero-indexed), or -1 if no match was found.
*/
public static function indexOfCaseInsensitiveString(arr:Array, searchingFor:String, fromIndex:uint = 0):int {
var lowercaseSearchString:String = searchingFor.toLowerCase();
var arrayLength:uint = arr.length;//Retrieving array length is expensive, optimization
for(var index:uint = fromIndex; index < arrayLength; index++){
var element:* = arr[index];
if(element is String && element.toLowerCase() == lowercaseSearchString){
return index;
}
}
return -1;//It wasn't found in the array.
}
You could then call it via ArrayUtils.indexOfCaseInsensitiveString(<your array>, <your string>). The fromIndex is just there to mimic the regular indexOf (principle of least surprise; if I say it's "indexOf with case-insensitive string search", why would that affect fromIndex?).
Regular Expressions may be used to achieve this using the case insensitive flag.
function findTargetIndex(needle:String,heystack:Array):int
{
var straw:String;
var magnet:RegExp = new RegExp(needle,"i");//"i" flag makes the search case insensitive.
//can also be done with magnet.ignoreCase = true;
for (var x:int = 0; x < heystack.length; x++)
{
straw = heystack[x];
if (straw.search(magnet) > -1) return x;
}
return -1;
}
The above function would search the array looking for any element that contains your search string. You can limit it to matching whole strings only by altering the RegExp;
var magnet:RegExp = new RegExp("^"+needle+"$","i");
^ matches the beginning of a string, $ matches the end, meaning the whole string must match the whole expression.
disclaimer: I havn't compiled this code, this is just to demonstrate how I would go about it.
you should check nulls and non-string variables. you should use Vector.<String> instead of Array
nope, there is none.
the simplest way:
function getCaseInsensitiveIndexOf(needle:String, haystack:Array):int
{
var index:int = -1;
if(needle != null)
{
index = haystack.indexOf(needle.toUpperCase());
if(index == -1)
index = haystack.indexOf(needle.toLowerCase());
}
return index;
}
// bellow is my first answer, but its overkill
you have to normalize the content of the array beforehand.
you possibly want to normalize a copy of it actually, so you don't loose any detail.
function getNormalizedVersionOf(target:Array):Array
{
var copy:Array = [];
for(var i:int = 0; i < target.length; i++)
{
copy[i] = (target[i] as String).toUpperCase(); // or .toLowerCase()
}
return copy;
}
and when you search, you search on the normalized copy
function getItemIndex(searchFor:String):int
{
var s:String = searchFor.toUpperCase();
return mNormalized.indexOf(s); //if you have the copy array as a class member called mNormalized
}
I have an ArrayCollection of a list of usernames and user id's. In this list there are duplicates that I need to remove. I've searched the internet and while there are a lot of example of this using Arrays, I can't find any clear examples using ArrayCollection's.
The should be simpler then the other solution.
function removeDuplicatesInArray(val:*, index:uint, array:Array):Boolean {
return array.indexOf(val) == array.lastIndexOf(val);
}
function removeDuplicatesInCollection(collection:ArrayCollection):ArrayCollection {
collection.source = collection.source.filter(removeDuplicatesInArray);
return collection;
}
Here's what I found after quick googling.
//takes an AC and the filters out all duplicate entries
public function getUniqueValues (collection : ArrayCollection) : ArrayCollection {
var length : Number = collection.length;
var dic : Dictionary = new Dictionary();
//this should be whatever type of object you have inside your AC
var value : Object;
for(var i : int= 0; i < length; i++){
value = collection.getItemAt(i);
dic[value] = value;
}
//this bit goes through the dictionary and puts data into a new AC
var unique = new ArrayCollection();
for(var prop:String in dic){
unique.addItem(dic[prop]);
}
return unique;
}
If you find solutions for the array you can do the same with the ArrayCollection. You can change arrayCollection.source and arrayCollection will be changed too. In general, we can assume that ArrayCollection is wrapper for Array.
Array contain a filter function and we can make use of it as following.
var ar:Array = ["Joe","Bob","Curl","Curl"];
var distinctData = ar.filter(function(itm, i){
return ar.indexOf(itm)== i;
});
Alert.show(distinctData.join(","));
Or better yet
Array.prototype.distinct = function():*
{
var arr:Array = this as Array;
return arr.filter(function(itm, i){
return (this as Array).indexOf(itm)== i;
},arr);
};
var ar:Array = ["Joe","Bob","Curl","Curl"];
Alert.show(ar.distinct());
function removeDuplicateElement(_arr:Array):Array{
//set new Dictionary
var lDic:Dictionary = new Dictionary();
for each(var thisElement:* in _arr){
//All values of duplicate entries will be overwritten
lDic[thisElement] = true;
}
_arr = [];
for(var lKey:* in lDic){
_arr.push(lKey);
}
return _arr;
}
What is the difference between the code (i) and (ii) written below ?
(i)
var obj:Object = new Object();
obj.attribute = value ;
(ii)
var obj:Object = new Object();
obj["key"] = value;
Are there any run-time implications if I write this :
var obj:Object = new Object();
obj.somekey = value1 ;
obj["someKey"] = value2 ;
Please explain.
The difference is in the lookup mechanism: If you use the dot syntax, the compiler will know at compile time that you are accessing a property of that object. If you use the bracket syntax, the actual lookup of the property is done at runtime, and there will have to be more type checking - after all, you could compose the key string dynamically, the value could change, or you could even be calling a function instead of a variable, etc.
The result is a significant difference in performance: Bracket syntax takes about three times as long to execute as dot syntax.
Here's a little speed test to illustrate my point:
var start : int = getTimer();
var obj:Object = { something : "something" };
for (var i : int = 0; i < 100000000; i++) {
var n:String = obj.something;
}
trace ("Time with dot syntax: "+(getTimer() - start));
start = getTimer();
for (i = 0; i < 100000000; i++) {
var o:String = obj["something"];
}
trace ("Time with bracket syntax: "+(getTimer() - start));
If the two were the same, except for notation, they should take exactly the same amount of time. But as you can see, this is not the case. On my machine:
Time with dot syntax: 3937
Time with bracket syntax: 9857
Is there a way to generically remove an object from an array?
(maybe not using array.filter or creating a new array)
Example:
var arr:Array= new Array();
//create dummy objs
for (var i:uint=0; i < 10; i++){
var someObject:SomeClassObject = new SomeClassObject();
someObject.Name ="Amit"+ i;
someObject.Site="http://www.mysite.com/"+i;
//...many more props
arr.push(someObject);
}
//
removeElement("Amit4",arr);
removeElement("Amit8",arr);
//...so on so forth
Currently im using array.splice() to remove object
for (var i:Number=0; i < arr.length; i++)
{
if (arr[i].Name == element)
{
arr.splice(i, 1);
}
}
I want to write removeElement in such a way that i can use it for different
types of objects.
currently removeElement becomes dependant on implmentation..
Suppose if i want to remove a file from array of files given file name..i wud have to
again write "removeElement" by changing criteria.
Also may be i can vary the criteria varing criteria?
example :
arr= removeElement("Site","http://www.mysite.com/6",arr)
will remove object from arr whose "Site" property is equal to "http://www.mysite.com/6"
(using above example)
ie. removeElement(criteria:object,criteria_value(s):object,arr)
Thanks All.
Use
if(array.indexOf(obj) != -1)
array.splice(array.indexOf(obj),1);
I think the most flexible approach is the one followed by Array::filter. It's up to the caller to determine whether an item should be filtered out of the list or not, through a function callback.
Now, if you want to do it in place, you could write a simple function like this:
function remove(list:Array,callback:Function):Array {
for(var i:int = list.length - 1; i >= 0; i--) {
if(!callback(list[i])) {
list.splice(i,1);
}
}
return list;
}
This returns the list, as it could be convenient if you wanted to chain calls, but it acts on the array you passed instead of creating a new one.
Also note that it loops backwards. Otherwise, splice will get you bogus results.
You could use it like this:
var arr:Array = [1,2,9,10,455];
trace(arr);
function removeCallback(item:Number):Boolean {
return item < 10;
}
remove(arr,removeCallback);
trace(arr);
This way you are not restricted to equality (or inequality). The caller determines if the item should be kept or removed, by returning true or false respectively (to match filter). So, it's pretty much like filter, except it works in-place. If you want, you could also keep the same interface for the callback (passing the index of the item and a reference to the original array) to make it more coherent.
By the way, you can use strings as indices for an array, and then you can safely use the 'delete' keyword to delete an object from inside the "middle" (there's actually no "middle" in this situation :) of the array.
e.g.:
var arr:Array = new Array();
arr['o1'] = new Object();
arr['o1'].someproperty = true;
arr['o2'] = new Object();
arr['o2'].someproperty = true;
arr['o3'] = new Object();
arr['o3'].someproperty = true;
trace (arr['o2'].someproperty);
//Returns 'true'
trace (arr['o2']);
//Returns '[object Object]'
delete arr['o2'];
trace (arr['o2']);
//Returns 'undefined'
trace (arr['o2'].someproperty);
//Returns 'TypeError: Error #1010: A term is undefined and has no properties.'
The disadvantage is you won't be able to know the length of the array (arr.length will return 0), but you can of-course track it yourself...
Here is a generic function which will do what you want:
public static function removeItem(array: Array, propertyName: String, value: String): Array
{
var newArray: Array = [];
for (var index: int = 0; index < array.length; index++) {
var item: Object = array[index];
if (item && item.hasOwnProperty(propertyName)) {
if (item[propertyName] != value)
newArray.push(item);
}
}
return newArray;
}