Remove an Array Element (or add two array slices)

Monkey Forums/Monkey Programming/Remove an Array Element (or add two array slices)

Grey Alien(Posted 2013) [#1]
So yeah I tried this today and it won't compile:

	Method RemoveSubObject:Void(subObject:TGameObject)
		For Local i:Int = 0 To subObjects.Length() -1
			If subObjects[i] = subObject Then
				'Trim out the array slot.				
				subObjects = subObjects[0 .. i] + subObjects[i + 1 .. subObjects.Length()]
			EndIf
		Next		
	End Method

It will work if I remove either half of the bit where I'm adding the two array slices.

Obviously I can make this work by making a temporary array which is a copy of the first slice, then looping and copying the values from the second slice into it, then doing subObjects = tempArray at the end.

However, I just wondered if there was a quicker way and if I'm being dumb? I'm just guessing that arrays don't have an overload for the + operator.

I know I could use a List (and I do in other places). I was just interested to see how this could be achieved easily, if at all. Thanks!


Goodlookinguy(Posted 2013) [#2]
Couldn't you use something like this to merge the any arbitrary datatype arrays?

Class Array1D<A> Final
	Function Merge:A[]( toArray:A[], fromArray:A[] )
		Local toLen:Int = toArray.Length
		Local frLen:Int = fromArray.Length
		
		toArray = toArray.Resize(toLen + frLen)
		
		For Local i:Int = 0 Until frLen
			toArray[toLen + i] = fromArray[i]
		Next
		
		Return toArray
	End
End


subObjects = Array1D<DataType>.Merge(subObjects[0 .. i], subObjects[i + 1 ..])


This is what I do to merge arrays.

Also this line of yours
For Local i:Int = 0 To subObjects.Length() -1

can be changed to this to save from having to write '-1'
For Local i:Int = 0 Until subObjects.Length



Grey Alien(Posted 2013) [#3]
Ah nice way to do it, thanks. Good call on the Until as well. I guess I'm just stuck in "To" mode since I was 9.


muddy_shoes(Posted 2013) [#4]
I just wondered if there was a quicker way


Which meaning of "quicker" are you using here? Quicker at runtime or quicker at typing time?

For speed you'd want to avoid taking two slices and sticking them together. Doing so would involve constructing an array for each slice, plus the data copying, and then another array and two loads of data copying for the result. Ideally Monkey would have an ArrayCopy function that wraps the block copying that most targets support but it doesn't. In the absence of writing one yourself the best you can likely do is resize your array to a result array and then individually copy the elements beyond the removal.

This isn't tested and would need altering if you expected more than one entry of a value but it should show what I mean. You could also likely get a shade more speed if you knew that the element definitely was in the array (or most likely would be) but if the speed of this operation is that much of concern then you're probably using the wrong data structure.




Grey Alien(Posted 2013) [#5]
Yeah I actually meant quicker to type, which I know is lazy. But I guess I should just make a function like yours (thx) or Goodlookingguy's and then at least it will be quick to type in the future. Luckily it's not for a speed critical part of code, but it's still worth making it fast by avoiding making an extra array in case I have a different use in the future. To be honest if I had a giant array and needed to remove elements I'd be better of making sure it was an array of objects that I could just set a slot to null on, or have an active flag in each object and reuse them (already do something similar for particle pooling)


Samah(Posted 2013) [#6]
Take a look at Diddy's Arrays class. It has no dependencies.
https://code.google.com/p/diddy/source/browse/src/diddy/arrays.monkey