Removing an element from an array
BlitzMax Forums/BlitzMax Programming/Removing an element from an array
| ||
Hi all, okay, so say you have an array of a defined size. Let's assume I have an array inside which I'm storing vertex coordinates, and it has some 1,200 values in it (example). However, to do some optimizing, I'd like to know if it is possible to remove values from somewhere in the middle of the array, without having to take all values, store in another temporary array, and reconstruct the original array? I know that I could use lists - but I was wondering if there is a way to this with arrays. |
| ||
I don't think this is easily possible without use of an external array. You could do sth like for local i:int = deletepos until array.length-1 array[i]=array[i]+1 next which removes the item and leaves the last entry doubled (can be set to 0 seperately) but I doubt that this operation will be faster / equally fast to an newarray[]=arry[..i]+array[j..] (which could be what you searched for anyway). |
| ||
What I do when I need this is that when I remove an element from the array, I `move` the highest indexed element into that position. ie take the highest index element and overwrite the one you're removing, then just keep track of how many elements you're using. But this only works if the order of the elements doesn't matter. If you're using a vertex array I presume you also have an `index` array... so you technically probably don't need to do anything to deal with the gaps you're creating, unless you want to optimize things by having a smaller vertex array upload? As above, if you move the highest vertex element to overwrite the one you're removing then you just need to update any indexes in the index array that reference them. |
| ||
You can't memcopy but you can memmove http://msdn.microsoft.com/en-us/library/8k35d1fx%28v=vs.71%29.aspx An MSDN link but I'm sure this is cross platform. Although I was surprised when it compiled in blitzmax straight off, so I assume this is a function provided by the mingw compiler. Its a bit ugly too because I don't know how to "sizeof" in blitzmax. Any enlightenments greatfully received :) SuperStrict Local a:Int[] = New Int[100] Local count:Int For Local i:Int = 0 To 99 If ( i >= 30 And i <= 40 ) a[i] = 0 Else a[i] = count count :+ 1 End If Next For Local i:Int = 0 To 99 Print i + "= " + a[i] Next MemMove( (Byte Ptr a) + (30 * 4), (Byte Ptr a) + (41 * 4), 59 * 4 ) For Local i:Int = 0 To 99 Print i + "= " + a[i] Next |
| ||
memcpy and memmove are C Standard Library. They'll work almost literally anywhere. |
| ||
Might I suggest a linked list instead of an array? It's much easier to manipulate them, they can have multiple properties which is handy and removing things from the list is easy. Sadly, after years of coding php, I do sometimes find BMax frustrating with its array handling! But I guess that's what php is designed for. |
| ||
Unfortunately you can't upload a linked list of vertices or indices to VRAM (but I'm sure some clever shader writers could probably prove me wrong). |
| ||
Hi all, I thank you all for your suggestions :) Indeed, it seems a bit tricky, but matibee's way could be one way to go about it. I'll probably ultimately ending up using some kind of other temporary array and reconstruct the original one =/ @matibee - Its a bit ugly too because I don't know how to "sizeof" in blitzmax. Any enlightenments greatfully received :) [bbcode]SizeOf(yourArray)[/bbcode] :) |
| ||
Actually it was sizeof primitive data types, ie sizeof( int ) I was looking for. Just testing: "sizeof( a:int )" works ok |
| ||
Interesting, you can concatenate two arrays. Using slices, this will remove elements as well as decrease the size of the array.SuperStrict Local a:Int[100] Local count:Int For Local i:Int = 0 To 99 If i > 30 And i < 40 a[i] = 0 Else a[i] = count count :+ 1 End If Next For Local i:Int = 0 Until a.length Print a[i] Next a = a[0..31]+a[40..] For Local i:Int = 0 Until a.length Print a[i] Next Last edited 2012 |
| ||
I personally use something like...BeforeCut[] = TotalArray[0..CutPoint] AfterCut[] = TotalArray[(CutPoint+1)..TotalArray.Length] TotalArray = BeforeCut + AfterCut You can adjust the 'CutPoint' index to cut a single index out, or use 2 cutpoints to cut a whole section of indices out. Edit:- I'm curious though as to why you want to remake the array, there may be better alternatives, just asking before you get too deep and committed already. Last edited 2012 |
| ||
if the order of the array doesn't matter, set the value in the middle to the last value in the array and then remove the last value of the array. This is super fast and works for anything where the order of the array doesn't matter. |