|
-
Jun 17th, 2008, 03:06 AM
#1
Thread Starter
Junior Member
Array Control
Hi,
I have an array that contains 5 elements:
i.e.
a(0) = "A"
a(1) = "B"
a(2) = "C"
a(3) = "D"
a(4) = "E"
What I want to be able to do is remove the first element then add information to the end.
e.g.
a(0) = "B"
a(1) = "C"
a(2) = "D"
a(3) = "E"
a(4) = "F" ; <- New
a(0) = "C"
a(1) = "D"
a(2) = "E"
a(3) = "F"
a(4) = "G" ; <- New
etc.....
Is there an easy way to remove the first element in an array?
Thanks for any help.
pG
-
Jun 17th, 2008, 03:19 AM
#2
Re: Array Control
Do you need to retain the sort order? If so then you have no choice but to shift elements up. If you don't need sort order then you can swap element to be removed with last array element then resize array or clear content of last array element.
Another alternative is to use collections.
-
Jun 17th, 2008, 04:11 AM
#3
Thread Starter
Junior Member
Re: Array Control
Sort order is needed. I haven't used collections before. Do you have an example.
Cheers.
-
Jun 17th, 2008, 04:30 AM
#4
Re: Array Control
Something like this perhaps? From what I can see you don't want to remove any elements here, so a secondary array or a collection isn't really needed.
This one will loop through each array element starting from the 1st index (not 0), and set the element previous to it's entry, to match the currently evaluated element's entry. I.e. taking your example, the first time the loop runs, it will look at a(1) and place the value at this element, into a(0). Upon the next loop iteration, a(2) will be evaluated and used in much the same way...
Code:
Dim i as integer
for i = 1 to UBound(arrayName)
arrayName(i -1) = arrayName(i)
next i
arrayName(UBound(arrayname) = "F"
Last edited by alex_read; Jun 17th, 2008 at 04:34 AM.
-
Jun 17th, 2008, 07:31 AM
#5
Re: Array Control
In my opinion -- and bear in mind I'm a guy that loves arrays and hates collections -- an array is superior to a collection if you need to retain the order. Collections only shine if you don't care about the order.
Plus arrays have all that juicy speed.
Last edited by Ellis Dee; Jun 17th, 2008 at 07:36 AM.
-
Jun 17th, 2008, 07:33 AM
#6
Re: Array Control
 Originally Posted by purplegerbil
Is there an easy way to remove the first element in an array?
Have you considered a linked list? If adding and removing elements is more common than searching, a linked list may be the way to go.
-
Jun 17th, 2008, 08:12 AM
#7
Re: Array Control
Here is a little something:
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub Form_Load()
Dim strTest() As String
' some initial data
ReDim strTest(4)
strTest(0) = "A"
strTest(1) = "B"
strTest(2) = "C"
strTest(3) = "D"
strTest(4) = "E"
' remove the first item
strTest(0) = vbNullString
' copy remaining items one step to the beginning
CopyMemory ByVal VarPtr(strTest(0)), ByVal VarPtr(strTest(1)), UBound(strTest) * 4&
' mark last item to be vbNullString to avoid having two string variables pointing to the same string data
' (it would be crashingly dangerous to leave both to point to the same data)
CopyMemory ByVal VarPtr(strTest(UBound(strTest))), 0&, 4&
' now add the new item
strTest(4) = "F"
' show what we have
Debug.Print Join(strTest, " + ")
End Sub
There are a few important things here:- The first item or all to-be-removed items must be empty/uninitialized/vbNullString before the CopyMemory call.
- The last item is set to vbNullString via CopyMemory, otherwise there would be two array items pointing to the very same string. It would be dangerous to let things stay that way. Basically all "extra" items in the array must be set to vbNullString via CopyMemory after moving data closer to the beginning.
This trick as such works with object arrays, too. Of course, setting to Nothing instead of vbNullString (binarywise doing pretty much the same thing, zeroing and making sure memory reserved elsewhere is freed).
Last edited by Merri; Jun 17th, 2008 at 08:18 AM.
-
Jun 17th, 2008, 08:17 AM
#8
Re: Array Control
That is beyond cool. Now I finally understand what leinad's insertion sort does.
-
Jun 17th, 2008, 08:26 AM
#9
Re: Array Control
Just for an explanation for everyone, this avoids what happens when you manually loop strings in an array to new position: you would be making a chain of "remove old string, copy a string to it's place from next place, move to the next position and repeat". This just moves the pointers of the strings in the array, thus effectively doing far less stuff memorywise 
Or for a more practical comparison: you have an array of 1000 strings. Instead of making 999 new copies and 1000 removals of strings from memory, you're making one string removal, one movement copy and one pointer zeroing.
-
Jun 18th, 2008, 02:31 AM
#10
Thread Starter
Junior Member
Re: Array Control
Thanks for your replys.
When I first started to code this I did something like alex_reads example but thought it was a little slow for what I needed. I'm going to try out Merri's code and do a speed test.
pG
-
Jun 18th, 2008, 07:24 AM
#11
Re: Array Control
If I understand what you are doing then maybe this might be useful. I'm assuming that the array is of fixed size and that each new element goes to the end of the array and the oldest element gets bumped off.
Rather than shifting the data in the array you can keep track of the current free index which will increment each time you add an item. When the index reaches the end of the array it goes back to the start.
If you do this the data inside the array does not need to be shifted every time a new string is added.
You could control it with Module or Class to make it easier to use
Code:
Option Explicit
Private mNxtI As Long
Public Const MYARRAY_UB = 9
Public TheArray(MYARRAY_UB) As String
Public Sub AddString(Txt As String)
TheArray(mNxtI) = Txt
If mNxtI <> MYARRAY_UB Then mNxtI = mNxtI + 1 Else mNxtI = 0
End Sub
Property Get OldestIndex() As Long
OldestIndex = mNxtI
End Property
Property Get LatestIndex() As Long
If mNxtI Then
LatestIndex = mNxtI - 1
Else
LatestIndex = MYARRAY_UB
End If
End Property
And use it like
Code:
Private Sub Form_Load()
Dim i As Long, j As Long
For i = 65 To 90 'adds the letters A-Z, when the array runs out of space the oldest item is overwritten
AddString Chr$(i)
Next i
'Displaying the data last to first
For i = OldestIndex To MYARRAY_UB
Debug.Print TheArray(i);
Next i
For i = 0 To LatestIndex
Debug.Print TheArray(i);
Next i
Debug.Print
'Displaying the data first to last
For i = LatestIndex To 0 Step -1
Debug.Print TheArray(i);
Next i
For i = MYARRAY_UB To OldestIndex Step -1
Debug.Print TheArray(i);
Next i
Debug.Print
end sub
If at some point you need the array in order (when it's passed to another function for example) then you can use copymemory with a temporary buffer to reorder it.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|