delphi-collを使ってみる(3)

前々回の記事「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

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください