39

私は Delphi の初心者で、整数値の昇順でレコードを並べ替えるために、レコードの TList の Sort メソッドを呼び出す方法がわかりません。以下のような記録があります。

 type
   TMyRecord = record
     str1: string;
     str2: string;
     intVal: integer;
   end;

そして、そのようなレコードの一般的なリスト:

TListMyRecord = TList<TMyRecord>;

ヘルプ ファイルでコード例を見つけようとしたところ、次のものが見つかりました。

MyList.Sort(@CompareNames);

クラスを使用しているため、使用できません。そこで、少し異なるパラメーターを使用して独自の比較関数を作成しようとしました。

function CompareIntVal(i1, i2: TMyRecord): Integer;
begin
  Result := i1.intVal - i2.intVal;
end;

しかし、コンパイラは常に「十分なパラメータがありません」をスローします - で呼び出すとエラーが発生しますopen.Sort(CompareIntVal);。だから私はヘルプファイルに近づこうとしました:

function SortKB(Item1, Item2: Pointer): Integer;
begin
  Result:=PMyRecord(Item1)^.intVal - PMyRecord(Item2)^.intVal;
end;

PMyRecord をPMyRecord = ^TMyRecord;

関数を呼び出すさまざまな方法を試しましたが、常にエラーが発生します...

4

4 に答える 4

62

使用Sortする必要があるオーバーロードは次のとおりです。

procedure Sort(const AComparer: IComparer<TMyRecord>);

IComparer<TMyRecord>これで、 を呼び出して を作成できますTComparer<TMyRecord>.Construct。このような:

var
  Comparison: TComparison<TMyRecord>;
....
Comparison := 
  function(const Left, Right: TMyRecord): Integer
  begin
    Result := Left.intVal-Right.intVal;
  end;
List.Sort(TComparer<TMyRecord>.Construct(Comparison));

関数を匿名メソッドとして記述しましたComparisonが、単純な古いスタイルの非 OOP 関数、またはオブジェクトのメソッドを使用することもできます。

比較関数の潜在的な問題の 1 つは、整数オーバーフローが発生する可能性があることです。したがって、代わりにデフォルトの整数比較子を使用できます。

Comparison := 
  function(const Left, Right: TMyRecord): Integer
  begin
    Result := TComparer<Integer>.Default.Compare(Left.intVal, Right.intVal);
  end;

繰り返し呼び出すとコストがかかる可能性があるためTComparer<Integer>.Default、グローバル変数に格納できます。

var
  IntegerComparer: IComparer<Integer>;
....
initialization
  IntegerComparer := TComparer<Integer>.Default;

考慮すべきもう 1 つのオプションは、リストを作成するときに比較子を渡すことです。この順序を使用してリストを並べ替えるだけの場合は、その方が便利です。

List := TList<TMyRecord>.Create(TComparer<TMyRecord>.Construct(Comparison));

そして、リストを並べ替えることができます

List.Sort;
于 2012-11-06T13:45:47.990 に答える