IViewCursorその2 検索にむけてのソート

IViewCursorその1の続きです。
IViewCursorには

  • findFirst()
  • findLast()
  • findAny()

の3つのメソッドが定義されており、いずれも引数にObjectを取ります。
この引数のObjectは、IViewCursorに格納されているデータを検索するためのキーとなるオブジェクトです。
findFirst、findLastはキーにマッチする最初/最後のオブジェクトを検索します。
findAnyはキーにマッチするオブジェクトのうちのいずれかを返します。
findAnyの場合は順序に関係なく、適当なオブジェクトを返すようです。

これを踏まえて、次のようなコードを書いてみました。

  var list:ArrayCollection = new ArrayCollection();
  list.addItem({name:"a",no:4});
  list.addItem({name:"b",no:3});
  list.addItem({name:"a",no:2});
  list.addItem({name:"b",no:1});
  
  var cursor:IViewCursor = list.createCursor();
  //最初にマッチするnameが"a"のデータを検索
  var firstObject:Object = cursor.findFirst({name:"a"});
  trace(firstObject.no);      

イメージとしては、findFirstを呼ぶと、{name:"a",no:4}のデータが返ってきて"4"が出力される感じですが、実行すると

 Error: ビューがソートされていない場合は見つけることができません
  at mx.collections::ListCollectionView/http://www.adobe.com/2006/flex/mx/internal::findItem()
  at ::ListCollectionViewCursor/findFirst()

というエラーが発生します。どうもソート済みのカーソルでしかfind系のメソッドは使えないようです。

ArrayCollectionにはmx.collections.Sort型の「sort」というプロパティがあり、このプロパティを使用してソートを行います。
単純にソートする場合、Sortクラスのfieldsプロパティに対し、mx.collections.SortFieldの配列をセットします。
SortFieldには、ソートしたいプロパティ名をセットしておきます。

  var list:ArrayCollection = new ArrayCollection();
  list.addItem({name:"a",no:4});
  list.addItem({name:"b",no:3});
  list.addItem({name:"a",no:2});
  list.addItem({name:"b",no:1});
  
  var sort:Sort = new Sort();
  sort.fields=[new SortField("name")];//nameプロパティでソートする
  list.sort = sort;
  //ソート実行
  list.refresh();

  for each(var o in list){
    trace(o.name+":"+o.no);
  }

上記コードの場合、list中のデータの"name"プロパティを比較して、データを並び替えます。ソート結果は

a:2
a:4
b:3
b:1

と表示されます。nameプロパティは順番に並んでいますが、同じnameプロパティを持つオブジェクトがある場合でもnoプロパティにしたがってソートされてはいません。
nameプロパティでソート後、さらにnoプロパティでもソートしたい場合、

sort.fields=[new SortField("name"),new SortField("no")];

とします。こうすることで、nameプロパティが同じ場合、noプロパティを使用して比較することが出来、ソート結果は

a:2
a:4
b:1
b:3

となります。
これでArrayCollectionがソートされ、検索可能状態になります。