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がソートされ、検索可能状態になります。