Loop through a variant array from a variant?

How do I do this?

[code]Dim v As Variant = Array(“1”, “2”, “3”)
If v.IsArray Then
Dim values() As Variant = v

For Each value As Variant in values
System.DebugLog(Str(value))
Next
End If[/code]

I get a type exception on line 3.

Actually, it can be broken down to:

Dim v() As Variant = Array("1", "2", "3")

That should work, shouldn’t it?

No, because Array can be used with numbers or strings, not variants. You can create your own function like this:

Function VArray(ParamArray value As Variant) As Variant()
  return value
End Function

Please see the details of “Variant” in LR.

Dim v As Variant = Array("1", "2", "3") If VarType(v) > 4095 Then Select Case VarType(v)-4096 // String Case 8 MsgBox( "String") Dim values() As String = v Dim i As Integer For i=0 To Ubound(values) MsgBox( values(i)) Next Case Else // All Else End Select End If

Because all the parameters to Array() are Strings the value contained in v is a String array. The exception in line 3 is that String() can’t be assigned to Variant().

Kem has a good, sensible idea to easily make a Variant(). There’s also a super hack way: mix disparate enough data types and Array has to return a Variant() to contain them.

dim v() As Variant = Array("a", 0)

I thought anything could be assigned to a variant? For example,

Dim v As Variant = "John"

Works just fine. I’m not seeing why assigning an array shouldn’t work. Maybe it doesn’t, but shouldn’t it? If not, why?

Yes, anything can be assigned to a Variant, but when you assign that Variant to something else the types need to match.

dim sa() As String //String array

sa = Array(“1”, “2”, “3”) //here Array() returns a String array so the assignment works

dim values() As Variant = sa //exception, incompatible types String() to Variant()

All of the code below compiles and executes without erros in Xojo.

[code] Dim i As Integer
//
// Most probably, my misunderstanding of the requirement
//
Dim v As Variant = Array(“1”, “2”, “3”)
If VarType(v) > 4095 Then
Select Case VarType(v)-4096
// String
Case 8
MsgBox( “String”)
Dim values() As String = v
For i=0 To Ubound(values)
MsgBox( values(i))
// New values saved in v
values(i) = Trim(Str(i+10))
Next
values = v
For i=0 To Ubound(values)
MsgBox( values(i))
Next
Case Else
// All Else
End Select
End If

//
// Kem Tekinay’s version
//
Dim newV() As Variant
newV = VArray( 1, “2”, True)
For i=0 To Ubound(newV)
MsgBox(Str( newV(i)))
Next
//
// This part pasted after the successful compilation.
//
Function VArray(ParamArray value As Variant) As Variant()
return value
End Function

//
// doofus’s version
//
Dim newV2() As Variant
newV2 = Array(10, “ABC”, False)
For i=0 To Ubound(newV2)
MsgBox(Str( newV2(i)))
Next
[/code]

Yes, a variant can hold anything, but you cannot coerce an array of one type into an array of another type by simple assignment, and that’s what you’re trying to do with a() as variant = Array( string1, string2 ). The Array statement there will output a string array, so that’s all it can be assigned to. As others have pointed out, you can mix the types within the Array statement to force a Variant array, so this would work too:

a() as variant = Array( string1, string2, true )
a.Remove a.Ubound

But I like my function better. :slight_smile:

Variant can hold anything
Variant() can only hold an array of Variant. But each element can hold anything.

There is a vast difference between Variant and Variant().

I’m having the same problem but none of the solutions provided thus far work. I have a serialization/deserialization class and it works great on most classes I pass it. Deserializing a property that is an array of objects works, but I’m having problem serializing arrays of primitives.

I have a variant v.
When v is an array of Objects, this works fine:

dim vs() as Variant = v

But it blows up when it is an array if integers or strings.
I need a generic way to iterate through an array of primitives so I can properly serialize it.
If there isn’t a generic way to do it then there is something seriously wrong with the framework that needs to be fixed.

[quote=70573:@Brock Nash]I have a variant v.
When v is an array of Objects, this works fine:
dim vs() as Variant = v[/quote]
This does not define an array of objects, it defines an array of Variants, whereby every element can be of any built-in scalar data type or an object.

You iterate over an array of Variants like over any other, but to process an element of the array, you have to first check what the data type of the element is:

For i As Integer = 0 To vs.Ubound Select Case vs(i).Type Case Variant.TypeBoolean Dim b As Boolean = vs(i) ... Case Variant.TypeArray + Variant.TypeBoolean Dim bs() As Boolean = vs(i) ... Case ... ... Next
Xojo is a strongly typed programming language, so there is no way around this.

It is also important to realize that due to the strongly typed nature of Xojo, you can’t assign an array of any data type to an array of Variants. So you can’t do this:

Dim bs() As Boolean = Array(True, False) Dim vs() As Variant = bs // This won't compile

Yeah, this doesn’t help me. I don’t want to have to case it out. That’s ridiculous. Xojo should have a built in way to cast an array of something into an array of variants.

I built a utility method that does essentially allows you to cast “almost” any array into an array of variants. It’s the “almost” part that annoys me. There needs to be an absolute way to do this. Regardless, I have serialization complete and now I’m just working on deserialization for primitive arrays. Its sad that serialization and deserialization of objects was significantly easier than it is for primitives.

I’d rather say you comment is ridiculous - no offense.

You can not cast an array of booleans, integers, int64s or so to an array of variants. This is just not possible (memory layout-wise).

Yeah I’ve said this to you before - writing a generic serialization framework ISN’T POSSIBLE because introspection isn’t designed for it.
Sorry but I know I said this - and now you’ve hit that little brick wall

It was designed to fit & fulfill a specific need and this isn’t it

File a feature request but since it could break stuff it might not happen in the current framework & I have no idea about the new one