想了一夜终于写出了整个函数,欢迎测试,继续征集效率更高的方法:
function DecIndices(var Indices: TBoundArray;
const HighBounds,LowBounds: TBoundArray): Boolean;
var
I, J: Integer;
begin
{ Find out if we're done: all at zeroes }
Result := False;
{ Two arrays must be of same length }
Assert(Length(Indices) = Length(LowBounds));
Assert(Length(Indices) = Length(HighBounds));
for I := Low(Indices) to High(Indices) do
if Indices > LowBounds then
begin
Result := True;
break;
end;
if not Result then
Exit;
{ Find index of item to tweak }
for I := High(Indices) downto Low(LowBounds) do
begin
// If not reach zero, dec and bail out
if Indices > LowBounds then
begin
Dec(Indices);
Exit;
end
else
begin
J := I;
while Indices[J] = LowBounds[J] do
begin
// Restore high bound when we've reached zero on a particular dimension
Indices[J] := HighBounds[J];
// Move to higher dimension
Dec(J);
Assert(J >= Low(LowBounds));
end;
Dec(Indices[J]);
Exit;
end;
end;
end;
function CompareVarArray(const v1,v2:Variant):Boolean;
var
i,iDim:Integer;
LowBounds,HighBounds,Indices:TBoundArray;
vCell1,vCell2:Variant;
begin
Result := False;
Assert(VarIsArray(v1));
Assert(VarIsArray(v2));
iDim := VarArrayDimCount(v1);
if iDim <> VarArrayDimCount(v2) then
Exit;
SetLength(LowBounds,iDim);
SetLength(HighBounds,iDim);
for i := 1 to iDim do
begin
LowBounds[i-1] := VarArrayLowBound(v1,i);
if LowBounds[i-1] <> VarArrayLowBound(v2,i) then
Exit;
HighBounds[i-1] := VarArrayHighBound(v1,i);
if HighBounds[i-1] <> VarArrayHighBound(v2,i) then
Exit;
end;
Indices := Copy(HighBounds);
repeat
vCell1 := VarArrayGet(v1,Indices);
vCell2 := VarArrayGet(v2,Indices);
if not MyVarEqual(vCell1,vCell2) then
Exit;
until not DecIndices(Indices, HighBounds,LowBounds);
Result := True;
end;
function MyVarEqual(v1,v2:Variant):Boolean;
begin
Result := False;
if VarType(v1) <> VarType(v2) then
Exit;
if (not VarIsArray(v1)) and (not VarIsArray(v2)) then
Result := VarSameValue(v1,v2)
else
Result := CompareVarArray(v1,v2);
end;