Storing a constant array

I’d like to store an constant array for use by different methods. Right now I am doing this by storing it in a public App.Property, with an App.Method doing this on App.Open:

Dim s() As String = Array(item 1, item 2, item 3, ...) MyStoredArrayProperty = s()

It works, but I have a feeling that’s just not the recommended Xojo way to do this. Isn’t there a more direct way to keep that array for public use in the project?

Create a global method that acts like an array. That way other code can’t change the contents.

Thanks, as usual, Tim. With your suggestion, I searched on how to do that and found this relevant conversation:

https://forum.xojo.com/18410-methods-that-return-an-array/0

So now I have a method with a return type As String(), as follows:

Dim s() As String s.append "item1" s.append "item2" ... Return s()

With the above as a global method in a module, I can now access that array anywhere.

Optimization:

Static s() As String if UBound(s)=-1 then s.append "item1" s.append "item2" ... end if Return s()

That way, it keeps the array around instead of rebuilding it every time.

Ah, I see. Thanks, Andrew. I assume that the way I had it before, it would have grown larger and larger with each access. Is that right?

No, but you’re rebuilding the same array data each time.

Something to watch out for with Js approach is that if something gets the array and modifies it (changes an element, appendss, removes, redims, etc) then that also modifies your ‘constant’ array.

Then, Will, how would you create a constant array available throughout the project? I had initially thought I could create a well-formed string as a global Property and go from there. But I couldn’t figure out how to do that, if it’s indeed possible.

My original suggestion was a bit different than you implemented.

Function ConstantArray(index as integer) as String
  static theArray() as String = Array("a", "b", "c")
  return theArray(index)
End Function

It doesn’t allow any external code to affect the values. It acts like a one-sided array. You can retrieve a value, but you cannot set one.

To add to Tims approach, it’s missing the Ubound info. I’d set it up something like this if you need that.

[code]Private mTheArray() As String

Private Sub InitConstantArray()
mTheArray = Array(“a”, “b”, “c”)
End Sub

Function ConstantArray(index As integer) As String
if mTheArray.Ubound = -1 then InitConstantArray
return theArray(index)
End Function

Function ConstantArray_Ubound() As Integer
if mTheArray.Ubound = -1 then InitConstantArray
return mTheArray.Ubound
End Function[/code]

Wouldn’t Tim’s approach fail to need the UBound condition in virtue of it being static? That is, doesn’t the UBound condition essentially result in the array being filled only once, which is what static does?

Just use Tims short bit of code
It will only be initialized once

Tim’s code works for me if I remove the parameter (index), and have it return String() instead of String. Like this:

Function ConstantArray as String() static theArray() as String = Array("a", "b", "c") return theArray() End Function

Then it works in the pre-existing code where I have bits like this:

For Each name As String In ContantArray() ...

I’m curious. How would I use Tim’s function as an “array” with the index Parameter included?

Function ConstantArray() as String()
static theArray() as String = Array(“a”, “b”, “c”)
return theArray
End Function

For Each name As String In ContantArray()
next

I tried that but found the compiler complaining about the missing index Parameter. So I took out the Parameter in the function definition and it worked as I noted above, which is exactly how you just spelled it out. Note Tim’s posted code includes that index Parameter:

Function ConstantArray(index as integer) as String static theArray() as String = Array("a", "b", "c") return theArray(index) End Function

You have to decide whether you want it to return an array, or an item from the array.

If you want just one item you’ll have to include an index parameter as Tim suggested. But then the For Each construct won’t work since you only have one item, not the whole array.

If you want the For Each construct to work, then you’ll need to return the whole array as Norman suggested, in which case you need to leave out the index parameter as he did in his example.

I misread :stuck_out_tongue:
Really the thing you want is “something that acts like an array but cannot be added to or otherwise manipulated”
So this means it should not allow you to append, remove, insert, etc
But you SHOULD be able to get at each item by its index, use indexof, etc

You cant do this with JUST an array and a handful of methods scattered about
But you CAN do it with a class that acts like an array but isn’t an array
Kind of a more advanced topic but thats really the right way to do this

[quote=262211:@Joe Huber]You have to decide whether you want it to return an array, or an item from the array.

If you want just one item you’ll have to include an index parameter as Tim suggested. But then the For Each construct won’t work since you only have one item, not the whole array.

If you want the For Each construct to work, then you’ll need to return the whole array as Norman suggested, in which case you need to leave out the index parameter as he did in his example.[/quote]

Ok. That’s what I figured when I removed the index Parameter from the function’s definition. I was just wondering if I missed something. Thanks, Joe.

HI Norman

I’ve always wondered if such a class can be made to cooperate nicely with providing the enumeration for For Each?

Do you know what interface/methods For Each uses for enumeration?

Cheers,
Joe

http://developer.xojo.com/xojo-core-iterable