Delete single element of an array

Just starting out? Need help? Post your questions and find answers here.
drahneir
Enthusiast
Enthusiast
Posts: 105
Joined: Tue Jul 18, 2006 4:18 pm
Location: JO42RM

Delete single element of an array

Post by drahneir »

Is it possible to delete a single element of an array, as is in C++ ?
gnasen
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Sep 24, 2008 12:21 am

Re: Delete single element of an array

Post by gnasen »

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
drahneir
Enthusiast
Enthusiast
Posts: 105
Joined: Tue Jul 18, 2006 4:18 pm
Location: JO42RM

Re: Delete single element of an array

Post by drahneir »

Thank you gnasen, this works.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Delete single element of an array

Post by wilbert »

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
PMV
Enthusiast
Enthusiast
Posts: 727
Joined: Sat Feb 24, 2007 3:15 pm
Location: Germany

Re: Delete single element of an array

Post by PMV »

This will crash, if the Array has only 1 element, you should
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
User avatar
skywalk
Addict
Addict
Posts: 4211
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Delete single element of an array

Post by skywalk »

Include Strings Too :wink:

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
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Delete single element of an array

Post by Tenaja »

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.
User avatar
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Delete single element of an array

Post by RichAlgeni »

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.
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Delete single element of an array

Post by Michael Vogel »

Don't have PB here (on my android device), not sure if this will work also...

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
Test...

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
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Delete single element of an array

Post by Trond »

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)
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Delete single element of an array

Post by Michael Vogel »

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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Delete single element of an array

Post by Kwai chang caine »

Thanks Michael for this nice code 8)
So it not works, i have found several problems in the passing parameters

Code: Select all

Procedure ArrayInsertString(name,element,content="")
I hope i have not damaged your code :oops: , but now it works :D

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
ImageThe happiness is a road...
Not a destination
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: Delete single element of an array

Post by Michael Vogel »

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

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

wilbert
PureBasic Expert
PureBasic Expert
Posts: 3942
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Delete single element of an array

Post by wilbert »

Michael Vogel wrote:Just started, I get the feeling, that the whole thing can't be done so easy...
Not so difficult :)

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
The only thing I don't understand is that it crashes the second time it is called if I use ReDim.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Delete single element of an array

Post by Trond »

Second point: where in the memory are the strings located?
Strings are just stored as a pointer. The real string could be anywhere.
Post Reply