我已经定义了一个动态数组类型如下:
TMyIntegerArray = array of integer:
Run Code Online (Sandbox Code Playgroud)
IndexOf如果它是一个TObject后代我想使用一个函数:
var
MyArray : TMyIntegerArray;
i : integer:
begin
//...
i := MyArray.IndexOf(10);
//...
end;
Run Code Online (Sandbox Code Playgroud)
目前,我发现的唯一解决方案是编写一个接受数组和目标值作为参数的函数:
function IndexOf(AArray : TMyIntegerArray; ATargetValue : integer; AOffset : integer = 0);
begin
Result := AOffset;
while(Result < Length(AArray)) do
begin
if(AArray[Result] = ATargetValue)
then Exit;
Result := Result + 1;
end;
Result := -1;
end;
Run Code Online (Sandbox Code Playgroud)
可以TMyIntegerArray输入类似的功能IndexOf吗?
更多信息:
目前,我正在使用Delphi2007,但我也有兴趣知道是否有任何方法可以在更新的Delphi版本中为数组类型添加方法.
LU *_* RD 13
在较新版本的Delphi(XE3 +)中,可以使用以下方法实现数组类型的方法record helpers:
program ProjectTest;
{$APPTYPE CONSOLE}
Type
TMyArray = array of integer;
TMyArrayHelper = record helper for TMyArray
procedure Print;
function IndexOf(ATargetValue : integer; AOffset : integer = 0): Integer;
end;
procedure TMyArrayHelper.Print;
var
i: Integer;
begin
for i in Self do WriteLn(i); // Use Self for variable reference
end;
function TMyArrayHelper.IndexOf(ATargetValue : integer; AOffset : integer = 0): Integer;
begin
Result := AOffset;
while(Result < Length(Self)) do
begin
if(Self[Result] = ATargetValue)
then Exit;
Result := Result + 1;
end;
Result := -1;
end;
var
myArr : TMyArray;
begin
myArr := [0,1,2]; // A neat way to populate a dynamic array (XE7+)
myArr.Print;
WriteLn(myArr.IndexOf(2));
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
注意:您可以跳过TMyArray类型声明并使用TArray<Integer>更宽松的类型解析.与记录助手一样,一个类型只能连接一个助手(将使用的助手是最接近范围的助手).
这种类型的帮助程序称为内部类型帮助程序,其中编译器在类型周围放置隐式记录结构.
尽管LU RD显示了您问题的直接解决方案,但我将基于泛型添加略有不同的方法.这具有在一个地方为不同阵列类型提供有效解决方案的优点.
对于支持泛型的Delphi版本,可以采用System.Generics.Collections中的TArray中使用的方式.这是引入函数IndexOf的类的直接扩展:
type
TArrayExt = class(TArray)
public
class function IndexOf<T>(const Values: array of T; const Item: T; const Comparer: IEqualityComparer<T>; Index, Count:
Integer): Integer; overload; static;
class function IndexOf<T>(const Values: array of T; const Item: T; const Comparer: IEqualityComparer<T>): Integer; overload;
static;
class function IndexOf<T>(const Values: array of T; const Item: T): Integer; overload; static;
end;
class function TArrayExt.IndexOf<T>(const Values: array of T; const Item: T; const Comparer: IEqualityComparer<T>; Index,
Count: Integer): Integer;
var
I: Integer;
begin
if (Index < Low(Values)) or ((Index > High(Values)) and (Count > 0))
or (Index + Count - 1 > High(Values)) or (Count < 0)
or (Index + Count < 0) then
raise EArgumentOutOfRangeException.CreateRes(@SArgumentOutOfRange);
if Count = 0 then
begin
Exit(-1);
end;
for I := Index to Index + Count - 1 do begin
if Comparer.Equals(Item, Values[I]) then begin
Exit(I);
end;
end;
Result := -1;
end;
class function TArrayExt.IndexOf<T>(const Values: array of T; const Item: T; const Comparer: IEqualityComparer<T>): Integer;
begin
Result := IndexOf<T>(Values, Item, Comparer, Low(Values), Length(Values));
end;
class function TArrayExt.IndexOf<T>(const Values: array of T; const Item: T): Integer;
begin
result := IndexOf<T>(Values, Item, TEqualityComparer<T>.Default, Low(Values), Length(Values));
end;
Run Code Online (Sandbox Code Playgroud)
一个简单的用例可能如下所示:
procedure Main;
var
arr: TArray<Integer>;
N: Integer;
begin
arr := TArray<Integer>.Create(5, 7, 3, 4, 2);
repeat
Readln(N);
N := TArrayExt.IndexOf(arr, N);
Writeln(N);
until false;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |