Solved

AS3 ---  Sorting Array

Posted on 2011-05-12
8
408 Views
Last Modified: 2012-05-11

I am loading an XML file to an Array and then trying to sort it.

Here is one item of many in the XML file:
 
  <main>
<item>
        <string0>fvg</string0>
        <inside>
          <string1>abc</string1>
          <string2>xyz</string2>
        </inside>
      </main>
<item>

Open in new window


I can sort it with no problem on <string0> but I don't know how to sort it on <string1> or <string2>


0
Comment
Question by:Angha110
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
8 Comments
 
LVL 29

Expert Comment

by:dgofman
ID: 35748702
If you are using Adobe Flex 4 this code should work for you

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                     xmlns:s="library://ns.adobe.com/flex/spark"
                     xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%" creationComplete="application1_creationCompleteHandler(event)">
      <fx:Script>
            <![CDATA[
                  import mx.collections.Sort;
                  import mx.collections.SortField;
                  import mx.collections.XMLListCollection;
                  import mx.events.FlexEvent;

                  protected function application1_creationCompleteHandler(event:FlexEvent):void
                  {
                        var sort:Sort = new Sort();
                        sort.fields = [new SortField("string", true)];
                        
                        //Sort parents first
                        var item:XMLListCollection = new XMLListCollection(source.item);
                        item.sort = sort;
                        item.refresh();

                        trace("\nSort by parent:\n" + item);
                        
                        //Sort sub notes
                        sort.fields = [new SortField(null, true)];
                        for each (var inside:XML in item.source.inside){
                              var xml:XMLListCollection = new XMLListCollection(new XMLList(inside.children()));
                              xml.sort = sort;
                              xml.refresh();
                              inside.setChildren(xml.copy());
                        }
                        
                        trace("\nSort by parent and children:\n" +item);
                  }

            ]]>
      </fx:Script>
      
      <fx:Declarations>
            <fx:XML id="source">
                  <main>
                        <item>
                              <string>fvg1</string>
                              <inside>
                                    <string>1</string>
                                    <string>3</string>
                                    <string>2</string>
                              </inside>
                        </item>
                        <item>
                              <string>fvg3</string>
                              <inside>
                                    <string>11</string>
                                    <string>33</string>
                                    <string>22</string>
                              </inside>
                        </item>
                        <item>
                              <string>fvg2</string>
                              <inside>
                                    <string>111</string>
                                    <string>333</string>
                                    <string>222</string>
                              </inside>
                        </item>
                  </main>
            </fx:XML>
      </fx:Declarations>
</s:Application>
0
 

Author Comment

by:Angha110
ID: 35748780
I am using Flash CS4
0
 
LVL 29

Expert Comment

by:dgofman
ID: 35748957
Ok try this

function toArray(list:XMLList):Array{
	var a:Array = [];
	for(var i:uint = 0; i < list.length(); i++)
		a.push(list[i]);
	return a;
};

for each (var item1:XML in source){
	var children1:Array = toArray(item1.children());
	children1.sortOn("string");
	item1.setChildren(new XMLList());
	for each (var c1:XML in children1){
		for each (var item2:XML in c1.inside){
			var children2:Array = toArray(item2.children());
			children2.sort();
			item2.setChildren(new XMLList());
			for each (var c2:XML in children2){
				item2.appendChild(c2);
			}
		}
		item1.appendChild(c1);
	}
}

trace(item1);

Open in new window

0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Angha110
ID: 35749080
Thank you for the code. I am going to try it right now.
Just to be clear, what if we have another nested tag in our XML file. do we need another loop for that.

 
<main>
      <item>
        <string0>fvg</string0>
           <inside>
              <deep>
                <string1>abc</string1>
                 <string2>xyz</string2>
              </deep>
           </inside>
     <item>
 </main>

Open in new window

0
 
LVL 29

Expert Comment

by:dgofman
ID: 35749142
For every nested tag you have to add for loop logic code is similar to this

for each (var item3:XML in c2.deep){
                  var children3:Array = toArray(item3.children());
                  children3.sort();
                  item3.setChildren(new XMLList());
                  for each (var c3:XML in children3){
                        item3.appendChild(c3);
                  }
            }
0
 

Author Comment

by:Angha110
ID: 35749410
Please see if this is right (having one more nested tag)

function toArray(list:XMLList):Array{
	var a:Array = [];
	for(var i:uint = 0; i < list.length(); i++)
		a.push(list[i]);
	return a;
};

for each (var item1:XML in source){
	var children1:Array = toArray(item1.children());
	children1.sortOn("string");
	item1.setChildren(new XMLList());
	for each (var c1:XML in children1){
		for each (var item2:XML in c1.inside){
			var children2:Array = toArray(item2.children());
			children2.sort();
			item2.setChildren(new XMLList());
			for each (var c2:XML in children2){
				item2.appendChild(c2);
			}
		}
		item1.appendChild(c1);
	}
	
	
	for each (var c2:XML in children2){
		for each (var item3:XML in c2.deep){
                  var children3:Array = toArray(item3.children());
                  children3.sort();
                  item3.setChildren(new XMLList());
                  for each (var c3:XML in children3){
                        item3.appendChild(c3);
                  }
            }
		item1.appendChild(c2);
	}
	
	
}

trace(item1);

Open in new window

0
 
LVL 29

Accepted Solution

by:
dgofman earned 500 total points
ID: 35749508
No, loops must be nested I attached code bellow, but you may use two level sorting if you want just code nested elements under depth
By modifying in my previous code
 
for each (var item2:XML in c1.inside){
to
for each (var item2:XML in c1.inside.deep){


Code bellow three levels sortings

for each (var item1:XML in source){
	var children1:Array = toArray(item1.children());
	children1.sortOn("string");
	item1.setChildren(new XMLList());
	for each (var c1:XML in children1){
		for each (var item2:XML in c1.inside){
			var children2:Array = toArray(item2.children());
			children2.sort();
			item2.setChildren(new XMLList());
			for each (var c2:XML in children2){
				for each (var item3:XML in c2.deep){
					var children3:Array = toArray(item3.children());
					children3.sort();
					item3.setChildren(new XMLList());
					for each (var c3:XML in children3){
						item3.appendChild(c3);
					}
				}
				item2.appendChild(c2);
			}
		}
		item1.appendChild(c1);
	}
}

Open in new window

0
 

Author Comment

by:Angha110
ID: 35749551
Thank you so much.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here are some practices and techniques that can be adopted into your Flash/Flex application development process. Note: Not all "performance tips" provide an immediately-recognizable benefit.   This article does not include timing validation data,…
The last time I worked with Flash and Socket connections was in AS1. A recent project required flash connecting to a Socket, and sending receiving information - we figured it would be easy enough - we all know about the socket policy documents and c…
The goal of the tutorial is to teach the user how to select the video input device. Make sure you have an input device that in connected and work and recognized by Adobe Flash Media Live Encoder and select it in the “video input” menu.
The goal of the tutorial is to teach the user how to use the auto adjust feature and what the different options do. When your video is not working right you can choose the auto adjust feature to help choose your settings.

718 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question