Function GetFromList(list,index)

Monkey Forums/Monkey Programming/Function GetFromList(list,index)

Volker(Posted 2012) [#1]
Hi,

I wan't to have a function that gets an object at index from a list.
Monkey lists do not support list.Get() anymore (why?).
The function shall work indenpendent from which kind of object
is in there.

Function GetFromList:Object(list:List<Object>, index:Int)
	Local count:int
	For Local o:Object = eachin list
		if count = index
			Return o
		EndIf
		count+=1
	Next
	Return NULL
End Function


This one fails with "Wrong number of type arguments for class List<T>"


Samah(Posted 2012) [#2]
Try using a Stack instead.


Volker(Posted 2012) [#3]
All my old code from Blitzmax is with lists. I want to stay with lists.


Shinkiro1(Posted 2012) [#4]
In Monkey every container such as lists have to have a specific type.
First, this ensures you can't just put anything in there which is bad practice anyway (you can still use polymorphism)
Also it avoids casting everytime you want an object of that container (bad for performance).

If you want to have indexed access, a list is the wrong container anyway. A stack like Samah mentioned would be a better fit.

Other alternatives are simple arrays or the ArrayList in diddy or extending a list with your own class.


NoOdle(Posted 2012) [#5]
Hi Volker, here is a quick example. It creates a static helper class:

[monkeycode]
Import mojo

Function Main : Int()

'// User which ever < Class > you wish and pass it your list
ListExtension< blah >.GetFromList( New List< blah >, 0 )

Return 1
End Function


Class ListExtension< T >

Function GetFromList : T( list : List< T >, index : Int )
Local count : int
For Local this : T = Eachin list
If count = index Then Return this
count = count + 1
Next
Return Null
End Function

End Class
[/monkeycode]

The other option as Gerry suggested below is to extend list:

[monkeycode]
Import mojo

Function Main : Int()

Local myList : ListExtension< Object > = New ListExtension< Object >
Local firstIndex : Object = myList.GetFromList( 0 )

Return 1
End Function


Class ListExtension< T > Extends List< T >

method GetFromList : T( index : Int )
Local count : int
For Local this : T = Eachin Self
If count = index Then Return this
count = count + 1
Next
Return Null
End method

End Class
[/monkeycode]


Gerry Quinn(Posted 2012) [#6]
You could add it to (or extend) monkey.list


Volker(Posted 2012) [#7]
Thanks guys, will have to think about it.


skid(Posted 2012) [#8]
If you are indexing lists then you do not want to stay with lists, you want to use stacks.


Samah(Posted 2012) [#9]
[monkeycode]Local foo:Stack<Bar> = New Stack<Bar>
foo.Push(something) ' like List.AddLast
foo.Pop(something) ' like List.RemoveLast
foo.Get(index)
foo.Set(index, value)[/monkeycode]
Just use a stack instead. It's a built-in class.


Volker(Posted 2012) [#10]
Stacks fail when removing objects in a eachin loop.
No concurrency check.


Samah(Posted 2012) [#11]
Diddy's ArrayList does a concurrency check and will throw an exception if you try to modify the list within an eachin loop. However, you can manually retrieve the Enumerator object and traverse back and forth, removing as you go by calling Remove() on the enumerator.


Chroma(Posted 2013) [#12]
Yeah I was indexing Lists too...I've just switched to stacks.


Skn3(Posted 2013) [#13]
Just another comment even though you are not using a list anymore. After some tests last year with blitmax I found it a very good middle ground between array and list access to avoid using the foreach enumerators. I would assume the same will occur in monkey and at least you wont be creating garbage enumerator objects.

( http://www.blitzbasic.com/Community/posts.php?topic=97352 )

So you could do your extended list method like so:
Class ListExtension<T> Extends List<T>
	Method GetFromList:T(findIndex:Int)
		Local node:= FirstNode()
		Local nodeIndex:Int
		While node
			If nodeIndex = findIndex Return node.Value()
			nodeIndex += 1
			node = node.NextNode()
		Wend
		Return Null
	End method
End Class


Some would argue it is pointless micro optimizations but well there is no harm in doing it this way and its not really that much more effort.