AS3 Sort a Collection of Objects? - actionscript-3

In AS3, how do i sort this list alphabetically? I'm not a programming expert and i've had a hard time just figuring this out.
var searchObject:Object = new Object();
var mapXML:XML;
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.load(new URLRequest("interactive-map.xml"));
xmlLoader.addEventListener(Event.COMPLETE, parseXML);
function parseXML(event:Event):void {
mapXML = new XML(event.target.data);
for each (var locationElement:XML in mapXML.maplocation) {
searchObject.locationname = locationElement.attribute("locationname");
searchObject.category = locationElement.attribute("category");
trace("Location Name: " + searchObject.locationname);
}
}

first you need to push elements to array/vector.
Then you can sort array with sortOn or sort methods.
Check sortOn/sort methods reference to find sorting options.
var searchObject:Object = new Object();
var searchObjectArray:Array = new Array
var mapXML:XML;
var xmlLoader:URLLoader = new URLLoader();
xmlLoader.load(new URLRequest("interactive-map.xml"));
xmlLoader.addEventListener(Event.COMPLETE, parseXML);
function parseXML(event:Event):void {
mapXML = new XML(event.target.data);
for each (var locationElement:XML in mapXML.maplocation) {
searchObject = new Object();
searchObject.locationname = locationElement.attribute("locationname");
searchObject.category = locationElement.attribute("category");
searchObjectArray.push(searchObject);//pushing elements to array
}
searchObjectArray.sortOn("locationname")//sorting array
for each ( var searchObjectElement:Object in searchObjectArray)
{
trace("Location name: " + searchObjectElement.locationname);//printing sorted array
}
}

Try something ike this:
var nodes:Array = [];
for each (var locationElement:XML in mapXML.maplocation) {
nodes[nodes.length] = locationElement;
}
nodes.sortOn(locationname);
I'm not sure if this will work with XML array elements. If it doesn't, try using sort() with a compareFunction.

I think you need to somehow wrap this in a collection class or map it over like Amy suggests, here's an example that uses an XMLCollection http://www.webdevotion.be/blog/2008/01/22/how-to-sort-an-xmllist-using-e4x/

Related

Why does (myMC.myArray = myOtherMC.myOtherArray;) cause any changes to myMC.myArray to also change myOtherMC.myOtherArray?

var myArray:Array = new Array();
var myMC:MovieClip = new MovieClip();
myMC.myArray = myArray;
trace(myMC.myArray[10]); //Output: undefined
var newMC:MovieClip = new MovieClip();
newMC.myOtherArray = myMC.myArray;
newMC.myOtherArray[10] = [];
newMC.myOtherArray[10][0] = 100;
trace(myMC.myArray[10]); //Output: 100
Why does that happen, and is there any way to avoid it?
EDIT:
Found a function that can clone associative arrays here.
Here is the function (from the above link):
function clone(source:Object):*
{
var myBA:ByteArray = new ByteArray();
myBA.writeObject(source);
myBA.position = 0;
return(myBA.readObject());
}
Does making the function return type "*" mean that it can be any type? or is it something specific to objects/arrays?
It's because you have passed a reference of the original array to the new clip. Arrays, as objects, are not primitives and therefore will always be referenced.
If you would like to clone an array, keeping the original intact, use this method:
var b:Array = a.concat();
b will be a new array. a can modified without changing b.

AS3 Event Handler stuck in infinite loop

I have a problem with my event handler. I am trying to use URLRequest to load some data from a database. But it's stuck in an infinite loop. Any suggestion of why is it looping, even after all the data is loaded?
The result is pushed into an array.
Code:
public function Listingdetailinfo()
{
somedata = SearchVectorTest.lists;
SrSend = new URLRequest("http://testurl/requestimage.php");
SrSend.method = URLRequestMethod.POST;
Arvariables = new URLVariables ;
SrSend.data = Arvariables;
SaLoader = new URLLoader();
SaLoader.dataFormat = URLLoaderDataFormat.TEXT;
Arvariables.data1 = somedata[0];
SaLoader.load(SrSend);
SaLoader.addEventListener(Event.COMPLETE,Asandler);
function searchVOs( pic:String )
{
this.pic = pic;
}
function Asandler(event:Event):void
{
trace(event.target.data);
// retrieve data from php call
var resultString:String = event.target.data;
trace(event.target.data);
// parse result string as json object and cast it to array
var resultArray:Array = JSON.parse(resultString) as Array;
var len:int = resultArray.length;
trace(resultString);
// create vector of SearchVO
var searchVOs:Array = new Array();
// get the length of the result set
var i:int;
for (i=0; i<len; i++)
{
searchVOs[i] = new Listingdetailinfo();
searchVOs[i].pic = resultArray[i].pic;
myArray.push(searchVOs[i].pic);
}
}
}
I assume your code represents the constructor of Listingdetailinfo class. The reason of your "infinite loop" is that you are creating new instances of this class in
searchVOs[i] = new Listingdetailinfo();

AS3 Object Name & Value

i am trying to return the Value of the Objects name, any help would be a huge help! thank you.
var o:Object = new Object();
var n:String = "NAME"
o[n] = "DATA";
for each (var p in o){
trace("name="+o[p]+" data="+p);
}
outputs -
name=undefined data=DATA
where it should be outputting -
name=NAME data=DATA
For looping thru Object properties, drop the "each":
var o:Object = new Object();
var n:String = "NAME"
o[n] = "DATA";
for (var p in o)
{
trace("name="+o[p]+" data="+p);
}
I believe you want to use a regular for loop vs a "for each" loop http://active.tutsplus.com/tutorials/actionscript/as3-101-loops/

AS3 Adobe AIR: Return xml string

I'm working in Flash CS6 with Adobe AIR 3.3 (for iOS) and having trouble returning an XML string to a textField.
It is tracing the proper information, and I've tried a few ways to return the trace but can't seem to quite get it... Here is my most recent try. Any suggestions? Thanks in advance.
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("http://www.someURL.php"));
//php file that echos xml
myLoader.addEventListener(Event.COMPLETE, init);
var fadedText:TextField;
var touchList:TouchList;
var textOutput:TextField;
var animateLeft:Tween;
var listArray:Array;
var item:TouchListItemRenderer;
var theXML:XML;
var days:Array = new Array("monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday");
var daySelected;
var businessNameArray:Array = new Array();
var businessLogoArray:Array = new Array();
var businessAddress:Array = new Array();
var distanceArrayDisplay:Array = new Array();
var distanceArrayCount = 0;
function init(e:Event = null):void
{
trace(myLoader.data);
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
myLoader.close();
// add our list and listener
var itemSizeCalculator = stage.stageHeight / 6;
touchList = new TouchList(stage.stageWidth, stage.stageHeight-itemSizeCalculator);
touchList.addEventListener(ListItemEvent.ITEM_SELECTED, handlelistItemSelected);
addChild(touchList);
touchList.x = stage.stageWidth;
// Fill our list with item rendreres that extend ITouchListRenderer.
for(var i:int = 0; i < theXML.food.length(); i++) {
if(theXML.food[i].monday != "un")
{
item = new TouchListItemRenderer();
item.index = i;
item.data = theXML.food[i].business;
item.name = theXML.food[i].business;
item.addEventListener(MouseEvent.CLICK, itemWasClicked);
item.itemHeight = itemSizeCalculator;
businessNameArray[i]= theXML.food[i].business;
businessLogoArray[i]=("http://www.logosURL.com/"+theXML.food[i].logo);
businessAddress[i]= theXML.food[i].address;
var fadedTextFormat:TextFormat = new TextFormat();
fadedTextFormat.bold = true;
fadedTextFormat.color = 0x999999;
fadedTextFormat.size = 14;
fadedTextFormat.font = "Helvetica";
fadedText = new TextField();
fadedText.height = 30;
fadedText.mouseEnabled = false;
fadedText.defaultTextFormat = fadedTextFormat;
item.addChild(fadedText);
fadedText.x = 75;
fadedText.y = 10;
distanceArrayDisplay.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest("http://maps.googleapis.com&origins=someAddress&destinations="+businessAddress[i]+"&mode=walking&language=en-en&sensor=false"));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
var logoLoader:Loader = new Loader();
item.addChild(logoLoader);
var logoURL:URLRequest = new URLRequest("http://www.myLogos.com/"+theXML.food[i].logo);
logoLoader.load(logoURL);
logoLoader.scaleX = .4;
logoLoader.scaleY = .4;
logoLoader.y = logoLoader.y + 5;
logoLoader.mouseEnabled = false;
var arrowGraphic:rightArrow = new rightArrow();
item.addChild(arrowGraphic);
arrowGraphic.x = stage.stageWidth - 5;
arrowGraphic.y = item.height/2;
touchList.addListItem(item);
}
}
}
function distanceCalculated(e:Event)
{
// trace(e.currentTarget.data);
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
var returnVar:String = (distanceXML.row.element.distance.text);
distanceArrayDisplay[distanceArrayCount].text = returnVar;
trace(returnVar);
distanceArrayCount++;
}
I am guessing that you are correctly reading the first XML, and that XML has a list of URLs that you want to load and then display some info from those on TextFields. Without knowing the structure of that XML I can't suggest you any working code, but I can point you on the right direction. For more info on reading/iterating XML on flash as3, please read: http://www.kirupa.com/developer/flashcs3/using_xml_as3_pg1.htm
//iterator var
var xml_read:uint=0;
//array of textfields for reference
var array_textFields:Array;
//config XML complete
function init(e:Event = null):void
{
array_textFields = new Array();
theXML = new XML(e.target.data);
theXML.ignoreWhitespace = true;
//this depends on the XML structure, please look at the article I linked
//for more info on how to iterate an XML
var i:uint=0;
for(someUrl in theXML..url)
{
var fadedText:TextField = new TextField();
//you should place each Textfield on different coord, otherwise
//they will all stack on top of each other and you will only see one
//for example:
fadedText.y = (fadedText.height+10)*i;
item.addChild(fadedText);
array_textFields.push(fadedText);
var distanceLoader:URLLoader = new URLLoader();
distanceLoader.load(new URLRequest(someUrl));
distanceLoader.addEventListener(Event.COMPLETE, distanceCalculated);
i++;
}
}
function distanceCalculated(e:Event):void
{
var distanceXML:XML = new XML(e.target.data);
distanceXML.ignoreWhitespace = true;
//retrieve information
var returnVar:String = (distanceXML.row.element.distance.text);
//set to textfield
TextField(array_textFields[xml_read]) = returnVar;
//increase iterator
xml_read++;
}
Please bear in mind that in ActionScript3, all network I/O is asynchronous. Usually EventListener functions don't return any value because you don't know when the data is ready. What you do is store a reference to where you want the data to go (in your case, a TextField variable) when the EventListener function is called asynchronously.

Sending textarea text to datagrid as object

I would like a text area that holds multiple strings to send its values to an array and the array to convert the string to an object. The objects then populate a datagrid. I can't really figure out where to go from here:
var arrayString:String = myTextArea.text;
var newArray:Array = arrayString.split(",");
var n:int=newArray.length;
while (n--)
{
newArray[n]=Number(newArray[n])
var obj:Object = new Object();
obj.label = newArray[n];
this.myDataGrid.addItem(obj );
}
var arrayString:String = myTextArea.text;
var newArray:Array = arrayString.split(",");
var n:int=newArray.length;
var dataProvider:ArrayCollection = new ArrayCollection;
while (n--)
{
newArray[n]=Number(newArray[n])
var obj:Object = { label: newArray[n] };
dataProvider.addItem(obj);
}
this.myDataGrid.dataProvider = dataProvider;