Results 1 to 11 of 11

Thread: Array Control

  1. #1

    Thread Starter
    Junior Member purplegerbil's Avatar
    Join Date
    May 2006
    Location
    Bradford, Yorkshire, UK
    Posts
    23

    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

  2. #2
    PowerPoster
    Join Date
    Nov 2002
    Location
    Manila
    Posts
    7,629

    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.

  3. #3

    Thread Starter
    Junior Member purplegerbil's Avatar
    Join Date
    May 2006
    Location
    Bradford, Yorkshire, UK
    Posts
    23

    Re: Array Control

    Sort order is needed. I haven't used collections before. Do you have an example.

    Cheers.

  4. #4
    Evil Genius alex_read's Avatar
    Join Date
    May 2000
    Location
    Espoo, Finland
    Posts
    5,538

    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.

    Please rate this post if it was useful for you!
    Please try to search before creating a new post,
    Please format code using [ code ][ /code ], and
    Post sample code, error details & problem details

  5. #5
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    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.

  6. #6
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Array Control

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

  7. #7
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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:
    1. The first item or all to-be-removed items must be empty/uninitialized/vbNullString before the CopyMemory call.
    2. 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.

  8. #8
    PowerPoster Ellis Dee's Avatar
    Join Date
    Mar 2007
    Location
    New England
    Posts
    3,530

    Re: Array Control

    That is beyond cool. Now I finally understand what leinad's insertion sort does.

  9. #9
    VB6, XHTML & CSS hobbyist Merri's Avatar
    Join Date
    Oct 2002
    Location
    Finland
    Posts
    6,654

    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.

  10. #10

    Thread Starter
    Junior Member purplegerbil's Avatar
    Join Date
    May 2006
    Location
    Bradford, Yorkshire, UK
    Posts
    23

    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

  11. #11
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    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
  •  



Click Here to Expand Forum to Full Width