我已经定义了一个动态数组类型,如下所示:
TMyIntegerArray = array of integer:
我想使用IndexOf
函数,如果它是TObject
的后代,我会这样做:
var
MyArray : TMyIntegerArray;
i : integer:
begin
//...
i := MyArray.IndexOf(10);
//...
end;
目前,我发现的唯一解决方案是编写一个接受数组和目标值作为参数的函数:
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;
TMyIntegerArray
类型可以使用IndexOf
等函数吗?
更多信息:
目前,我正在使用Delphi2007,但我也有兴趣了解是否有任何方法可以在新的Delphi版本中为数组类型添加方法。
答案 0 :(得分: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.
注意:您可以跳过TMyArray
类型声明,并使用TArray<Integer>
获得更宽松的类型解析。与记录助手一样,只有一个助手附加到一个类型(并且将使用的助手是最接近范围的助手)。
这种类型的帮助程序称为intrinsic type helper,其中编译器在类型周围放置隐式记录结构。
答案 1 :(得分:6)
虽然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;
一个简单的用例可能如下所示:
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;
答案 2 :(得分:1)
对于Delphi 2009及更高版本,您可以使用通用列表:
uses System.Generic.Collections;
var
MyArray : TList<integer>;
i : integer;
begin
MyArray := TList<integer>.Create;
MyArray.Add(3);
MyArray.Add(7);
MyArray.Add(10);
i := MyArray.IndexOf(10);
end;
在Delphi 2007中,您可以使用自定义记录:
type
TMyArray = record
private
TheArray : array of integer;
public
procedure Add(Value : integer);
function IndexOf(Value : integer) : integer;
function Length : integer;
end;
procedure TMyArray.Add(Value : integer);
var
i : integer;
begin
i := length(TheArray);
setlength(TheArray,i+1);
TheArray[i] := Value;
end;
function TMyArray.IndexOf(Value : integer) : integer;
var
i : integer;
begin
for i := 0 to length(TheArray)-1 do
begin
if TheArray[i] = Value then
begin
Result := i;
exit;
end;
end;
Result := -1;
end;
function TMyArray.Length : integer;
begin
Result := length(TheArray);
end;
procedure MyFunction;
var
MyArray : TMyArray;
i : integer;
begin
MyArray.Add(3);
MyArray.Add(7);
MyArray.Add(10);
i := MyArray.IndexOf(10);
end;