Page 1 of 1

[Solved] Removing One Item from an Array Variable

PostPosted: Mon Jun 04, 2018 9:29 pm
by rtellshow
Finding it hard to figure this out. So thanks in advance.

Lets say I have:
startArray = array(1,2,3,4,5)

I want either:
startArray(3) with the elements 1,2,4,5 or
newArray(3) with the elements 1,2,4,5

Is there anything like:
startArray(2).Remove ????

Can I used Redim preserve to preserve all but one element?

Or do I need to dump everything into a string, process the string, and then dump it back into an array?

Re: Removing One Item from an Array Variable

PostPosted: Mon Jun 04, 2018 10:33 pm
by Villeroy
With Python as macro language you have the full power of a mature programming language, including lots of functions for array manipulation. With Basic you have to write a loop which appends the wanted items to the new array.

Re: Removing One Item from an Array Variable

PostPosted: Mon Jun 04, 2018 10:52 pm
by Lupp
Code: Select all   Expand viewCollapse view
Function removeFrom1DarrayByIndex(p1Darray, pIndex As Long) As Boolean
removeFrom1DarrayByIndex = False
On Error Goto errorExit
l = Lbound(p1Darray) : u = Ubound(p1Darray)
For j = pIndex To u - 1
    p1Darray(j) = p1Darray(j + 1)
Next j
Redim Preserve p1Darray(l To u - 1)
removeFrom1DarrayByIndex = True
errorExit:
End Function

Sub test
a = Array(1,2,3,4,5)
Print removeFrom1DarrayByIndex(a, 2)
REM Inspect a in the 'Watch' window of the Basic IDE.
End Sub


Be careful. If the array the function operates on is referenced by additional variables the Redim will create a new array only referenced by the variable passed to the function. additional unexpected results may occur.

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Mon Jun 04, 2018 11:31 pm
by rtellshow
Villeroy...I guess I need to take on Python....

In the mean time I'll just use Lupp's code....does the job quite efficiently.

Thanks

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Tue Jun 05, 2018 12:00 am
by JeJe
An alternative to an array is to use the collection object - which does allow easy removal of items.

Code: Select all   Expand viewCollapse view

Dim test
Set test = New Collection

for i = 1 to 5
  test.Add(i)
next


test.remove(3)

for i = 1 to test.count
msgbox test.item(i)
next



Re: [Solved] Removing One Item from an Array Variable

PostPosted: Tue Jun 05, 2018 12:31 pm
by Lupp
If you (rtellshow) actually want to use one-dimensional arrays, I would suggest you replace the above given code by:
Code: Select all   Expand viewCollapse view
Function removeFrom1DarrayByIndex(p1Darray, pIndex As Long) As Boolean
removeFrom1DarrayByIndex = False
On Error Goto errorExit
l = Lbound(p1Darray) : u = Ubound(p1Darray)
h = p1Darray(u)
Redim Preserve p1Darray(l To u - 1)
REM Creates a new array. Disposes the original if no references are left.
For j = pIndex To u - 2
    p1Darray(j) = p1Darray(j + 1)
Next j
p1Darray(u - 1) = h
removeFrom1DarrayByIndex = True
errorExit:
End Function

Sub test
a = Array(1,2,3,4,5)
b = a
Print removeFrom1DarrayByIndex(a, 2)
REM Inspect a and b in the 'Watch' window of the Basic IDE.
End Sub

The slightly reworked function will still create a new instance of the array with one element less, but it will not at all afflict now the original array if there were additional variables referencing it. The roughly sketched version I gave first would mess the original up.
(If there was only one referencing variable, the original will be disposed anyway.)

The suggestion by "jeje" should be preferrable in many cases. During development of code in the IDE a little problem may be that you cannot view the elements in the 'Watch'.

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 6:26 am
by JeJe
One thing I often do is instead of keeping resizing the array is to have a buffer at the end of the array so that's unnecessary.


Code: Select all   Expand viewCollapse view




Sub test

   startArray = array(1,2,3,4,5,0,0,0,0,0)
   ubbuffer = 9
   ubarray = 4

   'remove second item in the array = 3
   item = 2
   for i = item to ubarray - 1
      startArray(i)= startArray(i+1)
   next
   ubarray = ubarray - 1

   'for i = 0 to ubarray 'show the bit of the array we're using
   'msgbox startArray(i)
   'next

   'removing the last item is easy, its just this
   ubarray = ubarray - 1

   'for i = 0 to ubarray 'show the bit of the array we're using
   'msgbox startArray(i)
   'next

   'adding an item to the end is also easy
   ubarray = ubarray + 1
   startArray(ubarray) = 5

   'for i = 0 to ubarray 'show the bit of the array we're using
   'msgbox startArray(i)
   'next

   'put the 3 back - that means moving items
   item =2
   ubarray = ubarray + 1
   for i = ubarray to item +1 step -1
      startArray(i)= startArray(i-1)
   next
   startArray(2) = 3

   for i = 0 to ubarray 'show the bit of the array we're using
      msgbox startArray(i)
   next

End Sub




(Windows has an api function called Copymemory which enables fast movement of items in an array. In my experiments with it in OOBasic it didn't work with anything except the first item in the array unfortunately.)

Edit: You only need to redim if the size of the buffer is going to be exceeded.

If the order of the items in the array is unimportant then all you have to do is swap the item you want to remove with the last item and removing and adding items is always really easy.
Code: Select all   Expand viewCollapse view

startArray(itemposition) = startArray(ubarray)
ubarray=ubarray-1


Edit2:

If the order of the items in the array is unimportant then you could use the same trick with redimensing the array of course - just swap the item you want to remove with the last item and redim preserve to the smaller size.

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 11:32 am
by Lupp
To keep a buffer and to manage the used size explicitly is clearly a good idea in many cases. However, the Redim Preserve command, even if NOT actually changing the size, has the additional effect of detaching the redimensioned variable (in fact a pointer to a newly created array then) from other variables referencing the original array. That was the reason for what I placed the Redim Preserve above the statements changing contents in the reworked version of my code.

@JeJe: I also do not know a way in Basic to access the actual storage of an array. As I did a bit of "real programming" in Pascal mainly, I am missing the feasibility of absolute declarations heavily. I am aware, of course, of the rsiks and challenges coming with the concept in a (next to) untyped programming language. Variant arrays will not have a contiguous storage range as their data container at all in most cases, and will therefor not be eligible for real access. Having the facility only for strictly typed arrays of numeric data would anyway be helpful. Please tell me if you find a way.

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 12:36 pm
by JeJe
Lupp - try this - it doesn't work so I presume that OO arrays don't store items in contiguous memory. Visual Basic 6 has the VarPtr function for accessing memory locations - but OOBasic doesn't have that. You lose cross platform compatability with Windows specific code anyway and its going beyond what OO is meant for.

Code: Select all   Expand viewCollapse view
Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cbCopy As Long)
Sub Main
dim ar() as long
redim ar(10)
ar(3) = 60
ar(4) = 80
copymemory ar(0),ar(3),8
msgbox ar(0) '60 as should be
msgbox ar(1) 'should be 80 but returns 0

End Sub


Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 12:56 pm
by RPG
I think we can better ask to the OP why he does need to remove an item of an array. Also important is maybe to place an example. An example makes more clear.

Romke

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 1:10 pm
by JeJe
@Lupp This works if that's ever any use to you.
Code: Select all   Expand viewCollapse view


dim st as string,st2 as string

st = "Fish"
st2 = "XXXX"

copymemory st2,st,2
msgbox st2 'FiXX


@RPG

Its solved... me and Lupp are just digressing...

Re: [Solved] Removing One Item from an Array Variable

PostPosted: Wed Jun 06, 2018 1:16 pm
by RPG
JeJe wrote:Its solved... me and Lupp are just digressing...
I do trust your examples and also the examples of Lupp. I want have an example of the original problem there the examples of you and also the examples of Lupp do not expand knowledge of the API. Then using Python or Collection is better.

Romke