PDA

View Full Version : The Jist on TVariantArrays.



R0b0t1
11-10-2007, 02:54 PM
A TVariantArray is like a Python list (I'd give you a link, but my nets down right now *Google*). In Python, a list is an array of non-related data types. Why should you care? Because it might be the next best thing since TPointArrays (The sliced bread of Object Finding).

So... You probably don't want to know all the technical stuff so I guess I can just tell you how to use them. Its really simple, actually.


program TVA;

var
TestTVA: TVariantArray

begin
end.



Thats how simple it is to create one. Assigning one is just as simple:


program TVA;

var
TestTVA: TVariantArray

begin
TestTVA:= [1337];
end.




So, say we wanted to access that value. It'd be considered an integer, but you don't really have to treat it as one.


program TVA;

var
TestTVA: TVariantArray

begin
TestTVA:= [1337];
WriteLn(TestTVA[0]);
end.


And that would print "1337" in the debug box. Notice how that the value in TestTVA's first index is an integer though. This is a blessing and a curse: While it is easier to I don't know... ...not put quotes around something, it can be a headache for those with strong backgrounds in type-oriented programming. Although, you won't get errors if you cast it to an integer - rather, its just not needed. Now we can look at multi-type TVA's, the ones that truly use its full potential.


So, say we want to add another element:


program New;

var
TestTVA: TVariantArray;
I: Integer;

begin
TestTVA:= [1337, 'leet'];
end.



This makes this variant array what many though previously impossible: two distinct types in the same object. This leads us to one of a TVA's uses -- storing information whose type you may not know. To use this feature we can use a simple for loop.


program New;

var
TestTVA: TVariantArray;
I: Integer;

begin
TestTVA:= [1337, 'leet'];
For I:= 0 to 1 do
WriteLn(TestTVA[I]);
end.



Notice anything different? I didn't have to use any testing to figure out if I needed to use IntToStr or other casting method. Amazing, huh? This could be useful for ... oh, maybe just recieving raw values. Invent your own Ideas for once XD.

Next up, lets see how it fares with records...


program New;

var
TestTVA: TVariantArray;
TestTP : TPoint;

begin
TestTP.x:= 1;
TestTP.y:= 1;
TestTVA:= [1337, 'leet', TestTP];
end.


Ouch! If you try to compile that, you may notice you get a Runtime type mismatch. Seems like you can't insert records into TVAs. We might have better luck with arrays, though. (As you can see, this is like bracket-defining a multi-dimensional array. Except theres no types...)


program New;

var
TestTVA: TVariantArray;

begin
TestTVA:= [1337, 'leet', [1, 2, 3]];
end.


Success! It compiles. I'm guessing you can access it the same way...


program New;

var
TestTVA: TVariantArray;

begin
TestTVA:= [1337, 'leet', [1, 2, 3]];
WriteLn(TestTVA[2][1]);
end.


Dang. Gives and exception. Even with a cast! Dang.. Well, maybe with string arrays... Nope (Tried it, but it compiles, just can't write it). Sad. Thought it might work :\. Well, I guess you could try adding pre-defined arrays to it, not much different though.

( some code later )

Yes, it doesn't print it out, but it will compile it.


Well, can't think of anything I haven't told you. Hope this has taught you something! If I think of anything or someone asks about something, I'll be sure to add it.

Santa_Clause
11-11-2007, 05:20 AM
The only thing I've ever seen these used for is forms and Custom WriteLn.

R0b0t1
11-11-2007, 07:15 PM
But that doesn't mean they are completely useless, does it?

Santa_Clause
11-15-2007, 11:40 AM
Well, it just means I don't know what they're useful for.

Absence of usefulness is not the presence of uselessness.

HyperSecret
11-16-2007, 06:28 AM
yes i am confused also...the only thing i really understand is that you can have multiple types of variables in a single array...stings, integers, and also arrays...guessing you could throw a boolean; somewhere in there also? but where would you be able to define which one of the 'components' you want to use

Santa_Clause
11-16-2007, 08:31 AM
Use the array number...

program New;

var
TestTVA: TVariantArray;
TestTP : TPoint;

begin
TestTP.x:= 1;
TestTP.y:= 1;
TestTVA:= [1337, 'leet', TestTP];
end.

TestTVA[0] is an Integer : 1337.
TestTVA[1] is a String : leet.
TestTVA[2] is a TPoint : TestTP.

Maybe something like this would work:

function FindNumberInVariant : Boolean;
var
I : Integer;
TestTVA : TVariantArray;
begin
TestTVA := [1337, 'Nothing', True, 'Something', 1337];
for I := 0 to GetArrayLength(TestTVA) - 1 do
if TestTVA[i] = 1337 then
begin
WriteLn('TestTVA[' + IntToStr(I) + '] Contains Integer : 1337');
Result := True;
end;
end;

I get this error :


[Runtime Error] : Exception: Could not convert variant of type (String) into type (Double) in line 8 in script

It does the first one, and then has trouble converting 'Nothing' into something else.

Miitchyy
11-16-2007, 12:23 PM
You never made it break from the loop therefore it searched through all terms and couldn't convert the variant 'Nothing' into a number thus giving the error.

Try either
function FindNumberInVariant : Boolean;
var
I : Integer;
TestTVA : TVariantArray;
begin
TestTVA := [1337, 'Nothing', True, 'Something', 1337];
for I := 0 to GetArrayLength(TestTVA) - 1 do
if TestTVA[i] = 1337 then
begin
WriteLn('TestTVA[' + IntToStr(I) + '] Contains Integer : 1337');
Result := True;
Exit;
end;
end;

Or

function FindNumberInVariant : Boolean;
var
I : Integer;
TestTVA : TVariantArray;
begin
TestTVA := [1337, 'Nothing', True, 'Something', 1337];
for I := 0 to GetArrayLength(TestTVA) - 1 do
if (VarType(TestTVA[i]) = 3) then
if TestTVA[i] = 1337 then
begin
WriteLn('TestTVA[' + IntToStr(I) + '] Contains Integer : 1337');
Result := True;
end;
end;

R0b0t1
11-21-2007, 09:31 PM
Yeah, I've been having strange problems trying to get it to store types and retrieving information from arrays of arrays.