About Monkey 2 › Forums › General Programming Discussion › Monkey container filtering
Tagged: Lists Deques
This topic contains 5 replies, has 3 voices, and was last updated by 
 Pixel_Outlaw 1 year, 8 months ago.
- 
		AuthorPosts
 - 
		
			
				
August 19, 2017 at 10:38 am #9921
So I’ve been confused a bit since Monkey X, but what is generally the best way to clear all dead items from a container from various positions?
Do you form a deque and push(pop()) only the alive items to the back on the dequeue [length] many times??
Or do you simply create a new list and add the living items onto it then reassign it back to the old list like in the firepaint example? This seems like it will really hammer memory if you’re clearing dead items out each cycle and creating a new data structure.
Currently I’m working on a Monkey X project (I’ll migrate to Monkey 2 when done) and I need the best container and approach for filtering out many dead instances from the middle.
In many genres of game you’ll have enemies that suddenly have been killed and need to be filtered out from various positions in the container.
I actually think things like Map, Filter, and Reduce would be really nice to have for the containers so you can know they’re implemented efficiently. I’d make them destructive/mutating if possible.
Thanks!
P_OAugust 19, 2017 at 3:52 pm #9923For MonkeyX you can use List<T> container and call its Remove() method like this:
Monkey12345678910111213141516171819202122232425262728293031Import mojoFunction Main()Local list:=New List<GameObject>list.AddLast(New GameObject("one",True))list.AddLast(New GameObject("two"))list.AddLast(New GameObject("three"))list.AddLast(New GameObject("four",True))' filteringFor Local obj:=Eachin listIf obj.dead Then list.Remove(obj)NextFor Local obj:=Eachin listPrint "obj: "+obj.nameNextEndClass GameObjectField dead:BoolField name:StringMethod New(name:String,dead:Bool=False)Self.name=nameSelf.dead=deadEndEndIn Monkey2 we can write more powerfull code – because we can pass functions as parameters of other functions.
And we can write generic function to remove items by filter for any instance type.
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556Function RemoveInList<T>:Int( list:List<T>,filteringFunc:Bool(T) )Local count:=0Local it:=list.All()While Not it.AtEndIf filteringFunc( it.Current )it.Erase()count+=1Elseit.Bump()EndifWendReturn countEnd......Local list:=New List<Int>For Local i:=0 Until 20list.Add(i)NextLocal filter1:=Lambda:Bool(val:Int)Return (val Mod 4) = 0EndLocal filter2:=Lambda:Bool(val:Int)Return val>10 And val<14EndRemoveInList( list,filter1 )For Local i:=Eachin listPrint iNextRemoveInList( list,filter2 ) 'just pass other filter funcFor Local i:=Eachin listPrint iNextLocal list2:=New StringList( New String[]("one","two","three") )Local filter3:=Lambda:Bool(val:String)Return val.Length<4End' now use it for stringsRemoveInList( list2,filter3 )For Local i:=Eachin list2Print iNextOne bad thing here – we can’t write the only universal function for all containers (list, stack, map, etc…) because of language limitation:
Finally, IContainer is not a ‘real’ interface because Monkey2 does not yet support generic interface methods. This feature is planned for a future version of monkey2.
August 19, 2017 at 5:30 pm #9924Ah, that’s really interesting.
Thanks for the insight!For your Monkey X example:
Are you sure calling remove on the iterator is safe?
It’s been a source of dangerous and undefined behavior in many programming languages.
Just a surprising pattern to see if so.As far as passing functions:
Yep! I anticipate using passed functions quite a bit in Monkey 2. I’m very familiar with that style of programming.
I do it quite a bit in C++, Python, Common Lisp.August 19, 2017 at 10:11 pm #9930Remove seems safe inside a for next, not sure if there are other iterations available for monkey containers.
Monkey1234567891011121314#Import "<std>"Using std..Function Main()Print "delete test"Local list:=New List<String>()list.AddLast("one")list.AddLast("two")list.AddLast("three")For Local i:=Eachin listIf i="two" Then list.Remove(i)Print iNextEndAugust 20, 2017 at 3:24 am #9934Are you sure calling remove on the iterator is safe?
I know that other langs deny iterator changes, but I just tried it in monkey-x and it works.
In monkey2 don’t work but we have iterator.Erase() here.
August 20, 2017 at 5:08 am #9936Ok, thanks for the help guys!
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.