TList indexing?

BlitzMax Forums/BlitzMax Programming/TList indexing?

Warren(Posted 2004) [#1]
Is there no way to index a TList? Do I -have- to convert it into an array or use a "eachin" loop to access specific elements?

I tried using MyList[0] and MyList(0) and both produce errors.

Is this not possible?


Dreamora(Posted 2004) [#2]
You could use the OO structure of TList and go through the list yourself. ( using TList.first() and Link.after() etc )

but it is not possible with the non-OO functions


Michael Reitzenstein(Posted 2004) [#3]
Internally, Blitz would just iterate through the list x number of times anyway, so an EachIn wouldn't be any slower. But no, there isn't any native way to do this.

Just out of interest, I can't image a situation where you'd want to index a TList where it didn't make sense to just make it an array of objects - I'd like to see an example.


Warren(Posted 2004) [#4]
Yeah ... I'm current doing this sort of thing:

local array:Object[] = ListToArray( MyList )
local MyObj:MyObjectType = MyObjectType(array[MyIndex])
But I was hoping for something less hacky.


Michael Reitzenstein(Posted 2004) [#5]
Your list changes frequently enough that this is a problem, but you still want to access specific elements? Or is it just the syntax that you don't like?


Warren(Posted 2004) [#6]
Michael

It's not that hard to imagine. I want to have a dynamically growing array of items that I need to index directly for various reasons.

For example, I'm currently faking a 'stack' implementation by having a TList of objects, using ListAddFirst to push onto the stack and I'm wanting to do a "GetTop" function by indexing item 0. But I currently can't do that with converting to an array first...

Is there a better way? I'm more than willing to learn! :)


Dreamora(Posted 2004) [#7]
jepp :-)


function getTop:Type( List:TList )
  return Type( List.RemoveFirst() )
endfunction




Michael Reitzenstein(Posted 2004) [#8]
You've got me there! A bank would be the best thing to use for a stack, since it's got an internal size which is larger than what you size it to, so most of the time growing/shrinking it is instant. When using it to store objects, though, the syntax would be kind of ugly, and I can't figure out how to get BlitzMax to cast Object<->Int. Oh, and they'd have to be stored in a list elsewhere, too, so they aren't collected.

So yeah, I guess each of the three (obvious) ways you can solve the problem are hacky.


Dreamora(Posted 2004) [#9]
Michael: Why is the usage of OO ( type own methods ) hacky?
There are some quite usefull functions in there that have no "flat function equivalents" so OO can't be avoided in this case, at least if you don't create your own flat functions for it :)


Warren(Posted 2004) [#10]
Dreamora

I don't want to remove the first item, I want to retrieve it. :)


Dreamora(Posted 2004) [#11]
removefirst returns the first object in the list and removes it afterwards
you can use .first() if you want it to stay in the list

see linkedlist.bmx for full details what it actually does :)


Michael Reitzenstein(Posted 2004) [#12]
Michael: Why is the usage of OO ( type own methods ) hacky?

It's not. Iterating through a list to find the n-th object is.


Dreamora(Posted 2004) [#13]
ok there you are right :)
For something like that a 2 way linked list would be more suited to iterate from front and back to lower the amount of needed steps and calls.


Warren(Posted 2004) [#14]
Looking in LinkedList.bmx, I found what I needed:

Method ValueAtIndex:Object( index )

Thanks all!


eni(Posted 2004) [#15]
I looked through the module myself a few days ago but missed that method. Thanks for highlighting it to me!

It's not. Iterating through a list to find the n-th object is.


I agree but on the rare occasion such a thing is a necessity. Well, actually there are generally ways around it but they are even worse.


N(Posted 2004) [#16]
Looking in LinkedList.bmx, I found what I needed:

Method ValueAtIndex:Object( index )

Thanks all!


Thanks to you too- saved me some time there.


Warren(Posted 2004) [#17]
Noel

Least I could do after you posted your DrawImageBlock code. I was -just- arriving at a spot where I was like, "Oh man, don't tell me I can't draw a sub section of an image!" Really should be part of the base modules... Kinda mandatory for anyone doing UI code.

Thanks!


N(Posted 2004) [#18]
Yep, that's exactly what I'm using it for, actually.


taxlerendiosk(Posted 2004) [#19]
If you want a dynamically-growing array you *could* make an array wrapped in a type that uses slicing to increase its size every time the limit is reached, something like (entirely untested):

Type GrowingArray
  Field Array[100]
  Field Pointer

  Method New()
     Pointer = 0
  End Method

  Method AddElement(NewElement)
     if Pointer = Len(Array)-1
        Array = Array[..Int(Len(Array)*1.5)]
     endif
     Array[Pointer] = NewElement
     Pointer :+ 1
  End Method
End Type

...but there are various reasons it might not be appropriate, just throwing it out there.


Warren(Posted 2004) [#20]
COuld. But TList works perfectly fine. My lists aren't growing and shrinking every frame, just on certain actions within the UI. So a TList combined with the index accessor function are ideal...


AntonyWells(Posted 2004) [#21]
edit-nm, someone beat me to it.


FlameDuck(Posted 2004) [#22]
Erm, isn't this a perfect scenario for using a HashMap?


Warren(Posted 2004) [#23]
Seems like over kill. The list will contain less than 10 items at any given time, I just needed access to specific indices from time to time.

At any rate, problem solved guys! Thanks. :) Move on...