TArray.Sortで配列をソートする

デフォルトの比較クラスでソートする

TArray.Sortを使うと配列をソートすることができます。

数値の配列をソートする例

uses
  System.Generics.Collections, System.Generics.Defaults;
var
  Values: array[0..8] of Integer = (1,3,5,7,9,8,6,2,4);
  I: Integer;
begin
  TArray.Sort<Integer>(Values);
  for I in Values do
    Write(I);
end.

実行結果

123456789

文字列の配列をソートする例

uses
  System.Generics.Collections, System.Generics.Defaults;
var
  Values: array[0..3] of string = ('Carol', 'Bob', 'Alice', 'Dave');
  S: string;
begin
  TArray.Sort<string>(Values);
  for S in Values do
    WriteLn(S);
end.

実行結果

Alice
Bob
Carol
Dave

IComparerを継承したクラスで比較方法を指定してソートする

TArray.Sortの2番目の引数にIComparerを継承したクラスを指定することで、任意の条件で配列をソートすることができます。

サンプルコードに使用するレコード。

type
  TMyRecord = record
    I: Integer;
    S: string;
  end;

TMyRecordのIフィールドが大きい順番にソートする例

TMyRecordのIフィールドが大きい順番にソートする比較クラス

type
  TMyRecordComparer1 = class(TComparer<TMyRecord>)
  public
    function Compare(const Left, Right: TMyRecord): Integer; override;
  end;

function TMyRecordComparer1.Compare(const Left, Right: TMyRecord): Integer;
begin
  Result := (Right.I - Left.I);
end;

サンプルプログラム

var
  Values: array[0..3] of TMyRecord = (
    (I: 1; S: 'Carol'),
    (I: 3; S: 'Bob'),
    (I: 4; S: 'Alice'),
    (I: 2; S: 'Dave')
  );
  R: TMyRecord;

begin
  TArray.Sort<TMyRecord>(Values, TMyRecordComparer1.Create);
  for R in Values do
    WriteLn(Format('%d:%s', [R.I, R.S]));
end.

実行結果

4:Alice
3:Bob
2:Dave
1:Carol

TMyRecordのSフィールドが小さい順番にソートする例

TMyRecordのSフィールドが小さい順番にソートする比較クラス

type
  TMyRecordComparer2 = class(TComparer<TMyRecord>)
  public
    function Compare(const Left, Right: TMyRecord): Integer; override;
  end;

function TMyRecordComparer2.Compare(const Left, Right: TMyRecord): Integer;
begin
  Result := System.SysUtils.CompareStr(Left.S, Right.S);
end;

サンプルプログラム

var
  Values: array[0..3] of TMyRecord = (
    (I: 1; S: 'Carol'),
    (I: 3; S: 'Bob'),
    (I: 4; S: 'Alice'),
    (I: 2; S: 'Dave')
  );
  R: TMyRecord;

begin
  TArray.Sort<TMyRecord>(Values, TMyRecordComparer2.Create);
  for R in Values do
    WriteLn(Format('%d:%s', [R.I, R.S]));
end.

実行結果

4:Alice
3:Bob
1:Carol
2:Dave

比較をコールバックルーチンに委譲してソートする

System.Generics.Defaults.TDelegatedComparerクラスは、比較処理をコールバックルーチンに委譲します。

TMyRecordのSフィールドが小さい順番にソートする例

var
  Values: array[0..3] of TMyRecord = (
    (I: 1; S: 'Carol'),
    (I: 3; S: 'Bob'),
    (I: 4; S: 'Alice'),
    (I: 2; S: 'Dave')
  );
  R: TMyRecord;

begin
  TArray.Sort<TMyRecord>(Values, TDelegatedComparer<TMyRecord>.Construct(
    function(const Left, Right: TMyRecord): Integer
    begin
      Result := System.SysUtils.CompareStr(Left.S, Right.S);
    end
  ));
  for R in Values do
    WriteLn(Format('%d:%s', [R.I, R.S]));
end.

実行結果

4:Alice
3:Bob
1:Carol
2:Dave

コメント

  1. Pingback: 【Delphi Tips】StringListの要素を文字列の長さでソートする – いぬごや

コメントを残す

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