前々回の記事「delphi-collを使ってみる(1)」前回の記事「delphi-collを使ってみる(2)」の続きです。
ジェネリックを用いたコレクションのクラスライブラリdelphi-collのCollections.Lists.TList<T>をもう少し使ってみます。
■Opメソッド
OpメソッドはTEnexExtOps<T>を返します。
TEnexExtOps<T>はSelectメソッドとGroupByメソッドを提供します。
以下はTEnexExtOps<T>の使い方です。
■TEnexExtOps<T>.Select(メンバー名)、TEnexExtOps<T>.Select<型>(メンバー名)、
リストの要素のメンバー名の値の一覧を返します。
型を指定しない場合は汎用のTAnyクラス、型を指定した場合は指定した型を返します。
var
PersonList: TList<TPerson>;
Any: TAny;
Name: String;
BirthDate: TDate;
begin
PersonList := TList<TPerson>.Create;
PersonList.Add(TPerson.Create('John', EncodeDate(1984, 1, 4)));
PersonList.Add(TPerson.Create('Mary', EncodeDate(1955, 4, 11)));
PersonList.Add(TPerson.Create('Ken', EncodeDate(2001, 8, 23)));
PersonList.Add(TPerson.Create('Lidia',EncodeDate(1978, 3, 10)));
//型を指定しない場合
for Any in PersonList.Op.Select('FName') do
WriteLn(Any.AsString);
//=> John Mary Ken Lidia
//型を指定した場合
for Name in PersonList.Op.Select<String>('FName') do
WriteLn(Name);
//=> John Mary Ken Lidia
//要素の中で最も小さいFBirthDateの値を取得する
BirthDate := PersonList.Op.Select<TDate>('FBirthDate').Min;
WriteLn(DateToStr(BirthDate));
//=> 1955/04/11
■TEnexExtOps<T>.Select(メンバー名の配列)
引数にメンバー名の配列を渡すと、指定したメンバーの値を持つTView型を返します。
var
PersonList: TList<TPerson>;
View: TView;
begin
PersonList := TList<TPerson>.Create;
PersonList.Add(TPerson.Create('John', EncodeDate(1984, 1, 4)));
PersonList.Add(TPerson.Create('Mary', EncodeDate(1955, 4, 11)));
PersonList.Add(TPerson.Create('Ken', EncodeDate(2001, 8, 23)));
PersonList.Add(TPerson.Create('Lidia',EncodeDate(1978, 3, 10)));
for View in PersonList.Op.Select(['FName', 'FBirthDate']) do
WriteLn(View.FName, ' ', DateToStr(View.FBirthDate));
//=> John 1984/01/04
//=> Mary 1955/04/11
//=> Ken 2001/08/23
//=> Lidia 1978/03/10
//1980年以降生まれの人の名前と生年月日を取得する
for View in PersonList.Where(
function(P: TPerson): Boolean
begin
Exit(CompareDate(EncodeDate(1980, 1, 1), P.FBirthDate) = LessThanValue);
end).Op.Select(['FName', 'FBirthDate']) do
begin
WriteLn(View.FName, ' ', DateToStr(View.FBirthDate));
end;
//=> John 1984/01/04
//=> Ken 2001/08/23
■TEnexExtOps<T>.Select<型>()
要素の型を指定した型に変換した新しいコレクション返します。
type
TPerson = class(TObject)
public
FName: string;
FBirthDate: TDate;
constructor Create(const AName: string; const ABirthDate: TDate);
end;
TStudent = class(TPerson)
public
FId: Integer;
constructor Create(Id:Integer; const AName: string; const ABirthDate: TDate);
end;
var
PersonList: TList<TPerson>;
Student: TStudent;
begin
PersonList := TList<TPerson>.Create;
PersonList.Add(TStudent.Create(1, 'John', EncodeDate(1984, 1, 4)));
PersonList.Add(TStudent.Create(2, 'Mary', EncodeDate(1955, 4, 11)));
PersonList.Add(TStudent.Create(3, 'Ken', EncodeDate(2001, 8, 23)));
PersonList.Add(TStudent.Create(4, 'Lidia',EncodeDate(1978, 3, 10)));
//TPersonのリストからTStudentのリストを作成する
for Student in PersonList.Op.Select<TStudent>() do
WriteLn(Student.FId, ' ', Student.FName, ' ', DateToStr(Student.FBirthDate));
//=> 1 John 1984/01/04
//=> 2 Mary 1955/04/11
//=> 3 Ken 2001/08/23
//=> 4 Lidia 1978/03/10
■TEnexExtOps<T>.GroupBy<型>(関数)
グループ化したコレクションを返します。
関数はリストの要素を受け取り、型の戻り値を返します。
GroupByは関数の戻り値ごとにグループ化したコレクションを返します。
次のコードはリストの値を奇数と偶数に分けます。
var
List: TList<Integer>;
C: IEnexGroupingCollection<String, Integer>;
N: Integer;
begin
List := TList<Integer>.Create;
List.Add(1);
List.Add(2);
List.Add(3);
List.Add(4);
List.Add(5);
for C in List.Op.GroupBy<String>(
//奇数偶数を判別する関数
function(X: Integer): String
begin
if Odd(X) then Exit('奇数') else Exit('偶数');
end) do
begin
WriteLn(C.Key);
for N in C do WriteLn(N);
end;
//=> 奇数
//=> 1
//=> 3
//=> 5
//=> 偶数
//=> 2
//=> 4