Sorting an ArrayCollection using the SortField and Sort classes
Sometimes in life you just need data to be sorted. Whether its a case insensitive sort (for names) or a numeric sort (for, uh, numbers), you just want things sorted in a particular order.
This example demonstrates how you can take a bunch of random numbers in an ArrayCollection and sort them numerically in ascending order.
Download source (ZIP, 1K) | View MXML
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.collections.SortField; import mx.collections.Sort; import mx.collections.ArrayCollection; [Bindable] private var arrColl:ArrayCollection; /** This method gets called by the main mx:Application tag and initializes/populates the ArrayCollection object with a bunch of random numbers. */ private function init():void { var i:int; /* Initialize and populate the ArrayCollection object. */ arrColl = new ArrayCollection(); for (i = 0; i < 20; i++) { arrColl.addItem({data:getRandomNumber().toFixed(4)}); } } /** This method returns a random floating-point number between 0 and 10000. */ private function getRandomNumber():Number { return Math.random() * 10000; } /** This method gets called by the Button control's click handler and creates a new SortField and Sort object which are used to sort the ArrayCollection. */ private function button_click():void { /* Create the SortField object for the "data" field in the ArrayCollection object, and make sure we do a numeric sort. */ var dataSortField:SortField = new SortField(); dataSortField.name = "data"; dataSortField.numeric = true; /* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */ var numericDataSort:Sort = new Sort(); numericDataSort.fields = [dataSortField]; /* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */ arrColl.sort = numericDataSort; arrColl.refresh(); } ]]> </mx:Script> <mx:List id="list" dataProvider="{arrColl}" textAlign="right" labelField="data" width="100" /> <mx:Button id="button" label="sort items" click="button_click()" /> </mx:Application>
View source is enabled in the following example.
Peter deHaan
Peter deHaan currently works for Adobe on the Flex SDK QA team. While not working on Flex, Flash, and ColdFusion applications, Peter enjoys making up bios and writing in 3rd person. Peter's rarely updated blog can be found at blogs.adobe.com/pdehaan/, actionscriptexamples.com, airexamples.com, and coldfusionexamples.com.
-
Add Widgets (Content Sidebar)
This is your Content Sidebar. Edit this content that appears here in the widgets panel by adding or removing widgets in the Content Sidebar area.
38 Responses to Sorting an ArrayCollection using the SortField and Sort classes
-
Categories
- Accordion
- AccordionHeader
- ActionScript
- AddChild
- AdvancedDataGrid
- Alert
- alpha
- Animate
- AnimateProperties
- Application
- Application (Spark)
- ArrayCollection
- BarChart
- baseColor
- beta
- beta1
- beta2
- Bitmap
- Bitmap/BitmapData
- BitmapData
- BitmapFill
- BitmapFill (Spark)
- BitmapGraphic
- BitmapImage
- BitmapImage (Spark)
- BitmapImageResizeMode
- Border (Spark)
- BorderContainer (Spark)
- Box
- BuildInfo
- Button
- Button (Spark)
- ButtonBar
- ButtonBar (Spark)
- ByteArray
- Camera
- Charting
- CheckBox
- CheckBox (Spark)
- ClassFactory
- CollectionEvent
- Color
- ColorPicker
- ColorUtil
- ComboBox
- ComboBoxArrowSkin
- Compiler
- Component
- Component (Spark)
- Configuration
- Container
- ContextMenu
- ContextMenuEvent
- ContextMenuItem
- CSSCondition
- CSSSelector
- CSSStyleDeclaration
- CurrencyFormatter
- CursorManager
- Data Binding
- DataGrid
- DataGrid (Spark)
- DataGridColumn
- Date
- DateBase
- DateChooser
- DateField
- DateFormatter
- Debugging
- DefaultComplexItemRenderer
- DefaultTileListEffect
- DropDownList
- DropDownList (Spark)
- DropDownListButtonSkin
- DropDownListSkin
- DropShadowFilter
- E4X
- Effects
- Ellipse
- EmailValidator
- Embed
- Event
- Fade
- FileFilter
- FileReference
- fill
- Filters
- Flash
- Flash Integration
- FlashVars
- Flex 3 SDK
- Flex Builder
- Flex Builder 3
- Flex SDK
- Flex4
- FLVPlayback
- FocusManager
- FontLookup
- Fonts
- Form
- Form (Spark)
- FormHeading (Spark)
- FormItem
- FormItem (Spark)
- Forms
- FTETextField (Spark)
- FullScreen
- FullScreenEvent
- FxAnimateColor
- FxButtonBar
- FxCheckBox
- FXG
- FxHScrollBar
- FxHSlider
- FxList
- FxNumericStepper
- FxRadioButton
- FxRotate3D
- FxScroller
- FxTextArea
- FxTextInput
- FxToggleButton
- FxVScrollBar
- FxVSlider
- getStyleDeclaration()
- GradientEntry
- Graphic (Spark)
- HBox
- HDividedBox
- HGroup (Spark)
- HorizontalLayout
- HorizontalList
- HSBColor (Spark)
- HScrollBar (Spark)
- HSlider
- HSlider (Spark)
- HTML template
- ID3Info
- Image
- Image (Spark)
- ImageSnapshot
- itemRenderer
- JointStyle
- Label
- Label (Spark)
- Legend
- LegendItem
- LigatureLevel
- Line
- LinearGradientStroke
- LineScaleMode
- LinkBar
- LinkButton
- List
- List (Spark)
- Menu
- MenuBar
- Metadata
- MetadataEvent
- Model
- Mouse
- MouseCursor
- MouseEvent
- Move
- Namespace
- NavigatorContent (Spark)
- needsSWF
- NetConnection
- NetStream
- Nightly Builds
- NumberBaseRoundType
- NumberFormatter
- NumberValidator
- NumericCompare
- NumericStepper
- NumericStepper (Spark)
- ObjectProxy
- ObjectUtil
- paddingLeft
- paddingRight
- Panel
- Panel (Spark)
- Parallel
- Path
- PieChart
- PieSeries
- PieSeriesItem
- PopUpAnchor (Spark)
- PopUpButton
- PopUpManager
- ProgrammaticSkin
- ProgressBar
- PropertyChangeEvent
- QName
- RadialGradient
- RadioButton
- RadioButton (Spark)
- RadioButtonGroup
- RadioButtonGroup (Spark)
- Rect
- RegExp
- Regular Expressions
- Repeater
- RichEditableText
- RichText
- RichText (Spark)
- RichTextEditor
- Rotate
- Rotate3D (Spark)
- Scroller (Spark)
- Sequence
- setStyle()
- SimpleText
- SimpleText (Spark)
- skinClass
- Slider
- SliderEvent
- SolidColor
- SolidColorStroke
- Sort
- SortField
- Sound
- SoundEffect
- Spinner (Spark)
- SpriteVisualElement (Spark)
- StageDisplayState
- States
- StringUtil
- StringValidator
- StyleManager
- Styles
- SWFLoader
- SWFObject
- System
- SystemManager
- TabBar
- TabBar (Spark)
- TabNavigator
- TabStopFormat
- Text
- Text Layout Framework (TLF)
- TextArea
- TextArea (Spark)
- TextBox
- TextConverter
- TextEvent
- TextFlow
- TextFlowUtil
- TextFormat
- TextGraphic
- TextInput
- TextInput (Spark)
- TextLayoutFormat
- TextView
- Themes
- TileLayout
- TileList
- TileOrientation
- Timer
- TitleWindow
- TitleWindow (Spark)
- TLF
- ToggleButton (Spark)
- ToggleButtonBar
- ToolTip
- Transition
- Tree
- TruncationOptions
- UIComponent
- UIFTETextField
- Updater
- URLLoader
- URLRequest
- URLUtil
- URLVariables
- ValidationResultEvent
- Validator
- Validators
- VBox
- VDividedBox
- Vector
- VerticalLayout
- VerticalLayout (Spark)
- VGroup (Spark)
- Video
- VideoDisplay
- VideoElement
- VideoElement (Spark)
- VideoEvent
- VideoPlayer (Spark)
- VideoPlayerScrubBar
- ViewStack
- VScrollBar (Spark)
- VSlider
- VSlider (Spark)
- XML
- XMLList
- XMLListCollection
- ZipCodeValidator
- ZipCodeValidatorDomainType
- Zoom
-
Articles
- December 2010
- November 2010
- October 2010
- September 2010
- August 2010
- July 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
- March 2008
- February 2008
- January 2008
- December 2007
- November 2007
- October 2007
- September 2007
- August 2007
- July 2007
-
Meta


Thanks for the tip. Really useful. It would be also useful to know that to sort descending you need to add “dataSortField.descending = true;”
Have phun,
Andrei
Thanks andrei! I appreciate this tip.
If an ArrayCollection contains a number of Foo objects and Foo has an attribute an instance of the class Bar and Bar has an attribute of fizz, can a SortField be used to sort Foo’s by the fizz attribute? I’ve tried doing new SortField(‘bar.fizz’) but get a runtime error stating that bar.fizz isn’t a property of Foo — even though it is. Is there any way around this?
There is great!
Hey Peterd, if I want to sort by text what code should I replace for below?
dataSortField.numeric = true;
Thanks
valentineday,
I haven’t tested it, but you could either try passing “false”, or perhaps just comment out/delete that line altogether.
Also, if you want to do a non-case-sensitive text search, you may want to try setting the
caseInsensitiveproperty totrue.Peter
Hi,
I’m looking for the same answer for as Peter stated [is there a one..?];
peter Oct 3rd, 2007 at 12:51 pm
If an ArrayCollection contains a number of Foo objects and Foo has an attribute an instance of the class Bar and Bar has an attribute of fizz, can a SortField be used to sort Foo’s by the fizz attribute? I’ve tried doing new SortField(’bar.fizz’) but get a runtime error stating that bar.fizz isn’t a property of Foo — even though it is. Is there any way around this?
thanks,
-bader
Hi,
I to, am looking for a solution to the same problem as bader & peter
(If an ArrayCollection contains a number of Foo objects and Foo has an attribute an instance of the class Bar and Bar has an attribute of fizz, can a SortField be used to sort Foo’s by the fizz attribute? I’ve tried doing new SortField(’bar.fizz’) but get a runtime error stating that bar.fizz isn’t a property of Foo — even though it is. Is there any way around this?)
You see i needed to use a itemRenderer for each column in my datagrid meaning that i had to populate each column using the code “data.etc”, the problem comes into play when i want to sort a column that displays a child element of one of the objects in my arrayCollection, how do i go about doin this? Been battling for a day or two.
thanks,
jason
Hi,
Could you please give me an example to sort numeric data in XMLListCollection? Here is my sample XML
Thanks,
VIvke
vivek,
Here’s an example of sorting XMLListCollection using MXML and ActionScript:
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Script> <![CDATA[ import mx.collections.SortField; import mx.collections.Sort; private function sortByField(value:String, isNumeric:Boolean = false, isDescending:Boolean = false):Boolean { var sortField:SortField = new SortField(value); sortField.numeric = isNumeric; sortField.descending = isDescending; var sort:Sort = new Sort(); sort.fields = [sortField]; xmlListColl.sort = sort; return xmlListColl.refresh(); } ]]> </mx:Script> <mx:XMLListCollection id="xmlListColl"> <mx:source> <mx:XMLList> <group name="Esthetique" value="2997" cost="0.52" /> <group name="xx" value="652" cost="0.47" /> <group name="xyt" value="652" cost="0.54" /> <group name="sss" value="652" cost="0.23" /> <group name="ffsdfsd" value="652" cost="0.82" /> </mx:XMLList> </mx:source> <mx:sort> <mx:Sort> <mx:SortField name="@cost" numeric="true" descending="true" /> </mx:Sort> </mx:sort> </mx:XMLListCollection> <mx:Panel> <mx:DataGrid dataProvider="{xmlListColl}" width="100%"> <mx:columns> <mx:DataGridColumn dataField="@name" /> <mx:DataGridColumn dataField="@cost" /> <mx:DataGridColumn dataField="@value" /> </mx:columns> </mx:DataGrid> <mx:ControlBar> <mx:Button label="Sort by @name" click="sortByField('@name')" /> <mx:Button label="Sort by @cost" click="sortByField('@cost', true, true);" /> <mx:Button label="Sort by @value" click="sortByField('@value', true, true);" /> </mx:ControlBar> </mx:Panel> </mx:Application>Happy Flexing!
Peter
For another example of sorting XMLListCollection, see “Sorting XML documents using an XMLListCollection”.
Peter
This might be a really silly question, but how do you sort if instead of objects your array just contains strings, like this:
[0] = “a”;
[1] = “c”;
[2] = “b”;
What sort field would you use for that?!
Paul.
Paul,
Just use the simple sort!
If I call sort on a list then add any new items, do i have to ‘resort’ on each insert or is it automatic now that a sort instance has been applied to the list?
Dan,
I quickly tested and it appears that newly added items are automatically added into their sorted position.
Peter
It doesnt seem to be sorting very well for me, I seem to have some that are unsorted; are there any known bugs with this that you know?
I’m looking for the same example as peter and bader – ac.getItemAt(i).bar.fizz sorting – would love help w/ that!
I ran into the same issue. A fellow programmer clued me in that you can specify a compareFunction for the Sort object. In there, you can do your comparisons using your object properties. Worked like a charm.
How would one go about sorting by date? Do I need to create a custom comparitor? Thanks!
Tom,
Turns out that I have an example on that very topic: http://blog.flexexamples.com/2007/08/12/sorting-date-columns-in-a-datagrid/
Peter
hey very useful example thanks. I wanna know if the list constructed as sorted. I mean do we have to click sort button? Couldn’t we show the list sorted at initialization?
I need to loop thru my collection AFTER its sorted, but when I do I get empty data. Is there a trick to this?
maybe I should clarify… I have some XML data, a list of strings, say peoples names for instance. I want to sort the list, then number them, then insert a “Select All” at the top of the list (index zero). I can seem to either number them or sort them but not both. Immediately after I sort (and refresh), I try to loop through the newly sorted list but get empty values during a trace()??? This is where I would want to add in my numbering and also insert my “Select All” item.
Any thoughts here?
is there a trick to sorting on multiple object attributes in an array list?
@Anonymous,
None I can think of off the top of my head. Are you having a specific problem trying to sort by multiple properties?
Peter
Adobe Flex – Sorting an ArrayColleciton by Date
http://kuriakosejacobthomas.blogspot.com/2009/10/adobe-flex-sorting-arraycolleciton-by.html
Adobe Flex – Sorting an ArrayColleciton by Date
/**
* @params data:Array
* @return dataCollection:Array
**/
private function orderByPeriod(data:Array):Array
{
var dataCollection:ArrayCollection = new ArrayCollection(data);//Convert Array to ArrayCollection to perform sort function
var dataSortField:SortField = new SortField();
dataSortField.name = “period”; //Assign the sort field to the field that holds the date string
var numericDataSort:Sort = new Sort();
numericDataSort.fields = [dataSortField];
dataCollection.sort = numericDataSort;
dataCollection.refresh();
return dataCollection.toArray();
}
A few gotchas when working with ArrayCollections.
When sorting an ArrayCollection, any further items will be auto sorted. Even if you’re adding items through the source.contact() method.
It is best to to create a temporary copy of an ArrayCollection to be sorted. Sort it using the new Sort() object, then when done, copy back the sorted elements using .toArray(); and NOT the source.concat().
If you are using a class level ArrayCollection that has been sorted, and you are extending the parent class that this is declared in, adding items via the child class will be auto sorted unless you have sorted the collection through a proxy temporary local collection.
Best practice:
MyClassLevelCollection.disableAutoUpdate();
//creat temporary ArrayCollection for sorting.
//Then copy them back to the class level ArrayCollection
var tempLocalCollection:ArrayCollection = new ArrayCollection();
tempLocalCollection.source = MyClassLevelCollection.toArray();
var dataSortField:SortField = new SortField();
dataSortField.name = “CountryValue”;
dataSortField.numeric = true;
dataSortField.descending = true;
tempLocalCollection.sort = new Sort();
tempLocalCollection.sort.fields = [dataSortField];
tempLocalCollection.refresh();
//add the newly sorted objects
MyClassLevelCollection.source = tempLocalCollection.toArray();
MyClassLevelCollection.enableAutoUpdate();
Thanks Peter, but especially thanks to Chris.
My issue is that I’m not able to preserve the sort for some reason. The following displays accurately, but the sort is not preserved (date descending) on subsequent calls.
thanks for this very useful tip. It helps me, to sort my datagrid which is based on an array collection
Hi, i’m actually sorting directly on the Array source of the ArrayCollection, which you’ll see is done using just two lines of code, instead of instianciating Sort / SortField classes. It works for me, i don’t know how much it’ll impact the performances of bigger apps, but hey… that’s a nice workaround at least :)
var myAC:ArrayCollection = new ArrayCollection();
for ( var i:int = 0; i < 10; i++ ) {
myAC.addItem( { data: int(Math.random() * 200) } );
}
myAC.source.sortOn('data', Array.NUMERIC);
myAC.refresh();
thanks for this post…although I could have figured this out in a reasonable amount of time, your post allowed me to achieve my implementation much faster.
Hi,
Is there any way to sort currency values. I have a datagrid column where I show currency values. I get the data in $35.87 format. Can someone help me how to sort these values.
Thanks,
Nirmal Kumar Bhogadi
Much obliged, that was very useful info. Also posters for extra tips.
I still have not seen anyone answer on how to sort on multiple fields such as firstName and lastName or lastName and firstName. I have tried it by creating a sortField = firstName + lastName but if errors out. I tried creating two sort Fields and sort.Fields = [firstField,lastField] and I have tried sort.Fields = [firstField+lastField].
I have also set numeric = false
All have failed so far.
@Michelle,
Look at using a custom sort compare function: http://blog.flexexamples.com/2008/04/09/creating-a-custom-sort-on-a-datagrid-control-in-flex/
Peter
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.Sort;
import mx.controls.Alert;
import mx.controls.DateField;
import mx.utils.ObjectUtil;
import mx.utils.object_proxy;
[Bindable]
private var arrClldetails:ArrayCollection = new ArrayCollection([
{Fname:"Kranthi", Lname:"Kata", dob:"Sep 21,1978"},
{Fname:"Vasanth", Lname:"Lola", dob:"Jun 11,1979"},
{Fname:"Manoj", Lname:"Pati", dob:"July 12,1980"},
{Fname:"John McClain", Lname:"Mela", dob:"Feb 12,1972"},
{Fname:"Ross", Lname:"Geller", dob:"Jan 02,1973"},
{Fname:"Chandler", Lname:"Bing", dob:"Oct 12,1974"},
{Fname:"Monica", Lname:"Geller", dob:"Mar 30,1976"},
{Fname:"Racheal", Lname:"Green", dob:"Dec 12,1977"},
{Fname:"Feebe", Lname:"Bufae", dob:"Dec 05,1981"},
{Fname:"Joey", Lname:"Tribiyani", dob:"Apr 12,1975"},
{Fname:"Priya", Lname:"Katari", dob:"Mar 31,1982"}
]);
private var arrData:ArrayCollection ;
private function fnClick():void
{
var sortl:Sort=new Sort();
sortl.compareFunction=fnCompareFunction;
arrClldetails.sort=sortl;
arrClldetails.refresh();
// for (var i:Number=0;i< arrClldetails.length;i++)
// mx.controls.Alert.show(arrClldetails[i].Fname);
arrData=arr_copy(arrClldetails);
}
private function fnCompareFunction(ObjA:Object,ObjB:Object,fields:Array = null):int
{
var dateA:Date=fnDtfParceFunct(ObjA.dob,"MM/DD/YYYY");
var dateB:Date=fnDtfParceFunct(ObjB.dob,"MM/DD/YYYY");
return ObjectUtil.dateCompare(dateA, dateB);
}
public function fnDtfParceFunct(valueString:String, inputFormat:String):Date
{
return DateField.stringToDate(dateFormatter.format(valueString),inputFormat);
}
protected function button1_clickHandler(event:MouseEvent):void
{
var temp:ArrayCollection= arr_copy(arrClldetails);
var ss:String="";
for (var ii:Number=0;ii< temp.length;ii++)
ss += temp[ii].Fname+"\n";
mx.controls.Alert.show(ss);
var temp1:ArrayCollection= arr_copy(arrClldetails);
var ss1:String="";
for(var i:Number=arrClldetails.length-1;i != -1;i–)
{
arrClldetails[i]= arrClldetails[Math.abs(i - (arrClldetails.length-1))];
// ss += ""+Math.abs(i – (temp.length-1))+"\n";
// ss1 += ""+i+"\n";
// ss += arrClldetails[Math.abs(i - (arrClldetails.length-1))].Fname+"\n";
// ss1 += temp[i].Fname+"\n";
}
// for (var ii:Number=0;ii
//in the above code,the sort :cant modify the arrCldet //:wts the reason plz mail me
in the prev code the sort process did not modifies the main array collection.i accessed via the second data grid it shows only the unsorted array collection.But already sorted the list and then only i accessed tht..wts the reason
Hi!!
i have 2 lists. in the first list i am randomly generating 5 numbers. after that i am moving those through drag and drop in the second list. now when i m calling sort function the first list is sorted instead of the new list..can u help me with the code..??