Delete single element of an array
Delete single element of an array
Is it possible to delete a single element of an array, as is in C++ ?
Re: Delete single element of an array
you can use a macro for this, for example:
Code: Select all
Macro deleteArrayElement(ar, el)
For a=el To ArraySize(ar())-1
ar(a) = ar(a+1)
Next
Redim ar(ArraySize(ar())-1)
EndMacro
Macro debugArray(ar,text)
Debug text
For a=0 To ArraySize(ar())
Debug ar(a)
Next
EndMacro
Dim test.i(5)
For a=0 To 5
test(a) = a
Next
debugArray(test,"START")
deleteArrayElement(test, 2)
debugArray(test,"DELETE 2")
deleteArrayElement(test, 0)
debugArray(test,"DELETE 0")
CallDebugger
pb 5.11
Re: Delete single element of an array
Thank you gnasen, this works.
Re: Delete single element of an array
Alternative macro
Code: Select all
Macro deleteArrayElement(ar, el)
MoveMemory(@ar(el)+@ar(1)-@ar(0), @ar(el), @ar(ArraySize(ar())) - @ar(el))
ReDim ar(ArraySize(ar())-1)
EndMacro
Re: Delete single element of an array
This will crash, if the Array has only 1 element, you should
use SizeOf(Structure) to get the size of one element.
use SizeOf(Structure) to get the size of one element.

Code: Select all
Macro deleteArrayElement(ar, el, st)
MoveMemory(@ar(el)+SizeOf(st), @ar(el), @ar(ArraySize(ar())) - @ar(el))
ReDim ar(ArraySize(ar())-1)
EndMacro
Re: Delete single element of an array
Include Strings Too

Code: Select all
Macro arDelNthElement(ar, el, struc=ABC, Type=$)
; Defaults = String operation
; For non-String, set struc = Byte,Long,Double,etc., Type = L
If SizeOf(struc) <> SizeOf(ABC)
MoveMemory(@ar(el) + SizeOf(struc), @ar(el), @ar(ArraySize(ar())) - @ar(el))
Else ; String
; netmaestro: www.purebasic.fr/english/viewtopic.php?p=160630#p160630
ar(el) = #NUL#Type ; Free memory of deleted element
MoveMemory(ar() + 4 * el + 4, ar() + 4 * el, PeekL(ar() - 8) * 4 - 4 * el)
EndIf
ReDim ar(ArraySize(ar())-1)
EndMacro
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: Delete single element of an array
For a single element, why not just move everything up into its place and skip the ReDim? If you may do it a lot, then save the ReDim for a batch job.
- RichAlgeni
- Addict
- Posts: 935
- Joined: Wed Sep 22, 2010 1:50 am
- Location: Bradenton, FL
Re: Delete single element of an array
Just wondering for my own benefit..., would it be faster to use a Map for this, then FindMapElement and DeleteMapElement?
I'm not critiquing anyone's style, just thinking about how I might do it.
I'm not critiquing anyone's style, just thinking about how I might do it.
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Delete single element of an array
Don't have PB here (on my android device), not sure if this will work also...
Test...
PS: would be fine to have such (internal) commands (insert/delete element) for arrays with structures
Code: Select all
Macro ArrayInsertString(name,element,content="")
ReDim name(ArraySize(name())+1)
MoveMemory(name()+4*element-4,name()+4*element+,PeekL(name()-8)*4-4*element)
name(element)=content
EndMacro
Code: Select all
For i=1 To 10
s(i)=RSet("",i,"x")
Next i
ArrayInsertString(s,5,"Will this work?")
For i=1 To ArraySize(s())
Debug Str(i)+": "+s(i)+", "+Str(Len(s(i)))
Next i
PS: would be fine to have such (internal) commands (insert/delete element) for arrays with structures
Re: Delete single element of an array
Remember, that if the order of the elements doesn't matter, you can do it this way:
Code: Select all
Array(ElementToDelete) = Array(ArraySize(Array))
ReDim Array(ArraySize()-1)
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Delete single element of an array
The ArrayInsertString macro did not work, here's a quick and dirty procedure solution for that now. Hopefully the memory pointer of arrays can be manipulated like that with no side effects. It would be interesting for me, if structured arrays are kept in memory in a similar way -- this could speed up inserting/deleting elements a lot here...
Code: Select all
Procedure ArrayInsertString(name,element,content="")
Protected n=ArraySize(name())+1
ReDim name(n)
name(n)=content
n=PeekL(name()+4*n)
MoveMemory(name()+4*element-4,name()+4*element,PeekL(name()-8)*4-4*element)
PokeL(name()+4*element,n)
EndProcedure
Dim s.s(10)
For i=1 To 10
s(i)=RSet("",i,"x")
Next i
ArrayInsertString(s,5,"Will this work?")
For i=1 To ArraySize(s())
Debug Str(i)+": "+s(i)+", "+Str(Len(s(i)))
Next i
- Kwai chang caine
- Always Here
- Posts: 5494
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
Re: Delete single element of an array
Thanks Michael for this nice code
So it not works, i have found several problems in the passing parametersI hope i have not damaged your code
, but now it works

So it not works, i have found several problems in the passing parameters
Code: Select all
Procedure ArrayInsertString(name,element,content="")


Code: Select all
Procedure ArrayInsertString(Array name.s(1),element,content.s="")
Protected n=ArraySize(name())+1
ReDim name(n)
name(n)=content
n=PeekL(name()+4*n)
MoveMemory(name()+4*element-4,name()+4*element,PeekL(name()-8)*4-4*element)
PokeL(name()+4*element,n)
EndProcedure
Dim s.s(10)
For i=1 To 10
s(i)=RSet("",i,"x")
Next i
ArrayInsertString(s(),5,"Will this work?")
For i=1 To ArraySize(s())
Debug Str(i)+": "+s(i)+", "+Str(Len(s(i)))
Next i

Not a destination
- Michael Vogel
- Addict
- Posts: 2797
- Joined: Thu Feb 09, 2006 11:27 pm
- Contact:
Re: Delete single element of an array
I am curious, if Add/DeleteElement functions could be done easily with structured arrays as well. I just started to get an idea, how the structure will be organized in the memory.
Just started, I get the feeling, that the whole thing can't be done so easy...
First issue: "n" in the debug line can't be replaced by "test(i)-test(i-1)"
Second point: where in the memory are the strings located? Replacing "???" by "test(i)+4" does not work
Just started, I get the feeling, that the whole thing can't be done so easy...
First issue: "n" in the debug line can't be replaced by "test(i)-test(i-1)"
Second point: where in the memory are the strings located? Replacing "???" by "test(i)+4" does not work
Code: Select all
Structure type
int.i
text.s
EndStructure
Dim test.type(5)
For i=1 To 5
test(i)\int=Pow(10,i)
test(i)\text=Str(test(i)\int)
Next i
For i=1 To 5
n=test(i)-test(i-1)
Debug Str(i)+": @"+Str(test(i))+", "+Str(n)+" Byte >> "+Str(test(i)\int)+" = "+test(i)\text
;Debug Str(i)+": @"+Str(test(i))+", "+Str(n)+" Byte >> "+Str(PeekL(test(i)))+" = "+PeekS(???)
Next i
For i=1 To 5
Debug Str(i)+": "+Str(test(i)\int)+" = "+test(i)\text
Next i
Re: Delete single element of an array
Not so difficultMichael Vogel wrote:Just started, I get the feeling, that the whole thing can't be done so easy...

Code: Select all
Global.i _ArrSize_, _ArrElementSize_, _ArrElementAddr_
Macro ArrayRemoveElement(ar, el)
_ArrSize_ = ArraySize(ar())
If _ArrSize_ > 0 And el <= _ArrSize_
_ArrElementSize_ = @ar(1) - @ar(0)
_ArrElementAddr_ = @ar(el)
MoveMemory(_ArrElementAddr_ + _ArrElementSize_, _ArrElementAddr_, @ar(_ArrSize_) - _ArrElementAddr_)
PokeL(@ar() - 8, _ArrSize_); ReDim ar(_ArrSize_ - 1)
EndIf
EndMacro
Structure type
int.i
text.s
EndStructure
Dim test.type(5)
For i=1 To 5
test(i)\int=Pow(10,i)
test(i)\text=Str(test(i)\int)
Next i
For i=1 To 5
Debug Str(i)+": "+Str(test(i)\int)+" = "+test(i)\text
Next i
ArrayRemoveElement(test, 2)
For i=1 To 4
Debug Str(i)+": "+Str(test(i)\int)+" = "+test(i)\text
Next i
Re: Delete single element of an array
Strings are just stored as a pointer. The real string could be anywhere.Second point: where in the memory are the strings located?