Jump to content
Sign in to follow this  
Achilles

Two dimensional array delete

Recommended Posts

Achilles

This is based off _ArrayDelete()...

The result (for the example) is written to the Console so you can see what it does...

The code:

Dim $array[6][5]

For $a = 0 to 5 
    For $b = 0 to 4 
        $array[$a][$b] = $a * $b 
    Next 
Next

ConsoleWrite(@CRLF & @CRLF & '> ' & @TAB & '***THE ORIGINAL ARRAY***' & @CRLF)
For $a = 0 to 5 
    ConsoleWrite('!======$array[' & $a & '] is as follows: 0: ' & $array[$a][0] & @TAB & '1: ' & $array[$a][1] & @TAB & '2: ' & $array[$a][2] & @TAB & '3: ' & $array[$a][3]&  @TAB & '4: ' & $array[$a][4] &  @CRLF)
Next

_ArrayDelete2D($array, 1) 

ConsoleWrite(@CRLF & '> ' & @TAB & '***THE MODIFIED ARRAY***' & @CRLF)
For $a = 0 to 4 
    ConsoleWrite('!=====$array[' & $a & '] is as follows: 0: ' & $array[$a][0] & @TAB & '1: ' & $array[$a][1] & @TAB & '2: ' & $array[$a][2] & @TAB & '3: ' & $array[$a][3] & @TAB  & '4: ' & $array[$a][4] & @CRLF)
Next
ConsoleWrite(@CRLF & @CRLF)

Func _ArrayDelete2D(ByRef $avArray, $iElement)
    Local $passed = False
    
    If (Not IsArray($avArray)) Then
        SetError(1)
        Return ""
    EndIf
    
    ; We have to define this here so that we're sure that $avArray is an array
    ; before we get it's size.
    $iUpper = UBound($avArray)    ; Size of original array
    $iSubItems= Ubound($avArray, 2)
    
    ; If the array is only 1 element in size then we can't delete the 1 element.
    If $iUpper = 1 Then
        SetError(2)
        Return ""
    EndIf
    
    Local $avNewArray[$iUpper - 1][$iSubItems]

    For $a = 0 to $iUpper - 1 
        If $a = $iElement then 
            $passed = True 
        Else 
            If Not $passed then 
                For $b = 0 to $iSubItems - 1
                    $avNewArray[$a][$b] = $avArray[$a][$b] 
                Next 
            Else 
                For $b = 0 to $iSubItems - 1
                    $avNewArray[$a - 1][$b] = $avArray[$a][$b] 
                Next 
            EndIf
        EndIf 
    Next
    
    $avArray = $avNewArray

    Return 1
EndFunc

EDIT: Found and fixed a bug

Edited by Piano_Man

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites
Valuater

noticed a couple of things... but

you have

Local $avNewArray[$iUpper - 1][3]

setting the second arrays deminsion, shouldn't that be

Local $iUpper2 = UBound($avArray, 2)

Local $avNewArray[$iUpper - 1][$iUpper2 -1]

???

8)

EDIT... came back and saw your edit... still..

$numberOfSubitems does not have to be passed by the user, it can be found as i stated above

Edited by Valuater

NEWHeader1.png

Share this post


Link to post
Share on other sites
Achilles

noticed a couple of things... but

you have

Local $avNewArray[$iUpper - 1][3]

setting the second arrays deminsion, shouldn't that be

Local $iUpper2 = UBound($avArray, 2)

Local $avNewArray[$iUpper - 1][$iUpper2 -1]

???

8)

EDIT... came back and saw your edit... still..

$numberOfSubitems does not have to be passed by the user, it can be found as i stated above

Ok, I was wondering if there was some sort of way to do that.. Thanks

Edit: Fixed that... and by the way:

Local $avNewArray[$iUpper - 1][$iUpper2 -1]
Would only work if I wanted to downsize the second level too, the second part is just $iUpper2 Edited by Piano_Man

My Programs[list][*]Knight Media Player[*]Multiple Desktops[*]Daily Comics[*]Journal[/list]

Share this post


Link to post
Share on other sites
MvGulik

Suggestion(?)

Func _Array_RecordCleanup(ByRef $avArray, $fIndex = False, $vDelToken = '')
    ;; deleted all records that have a $vDelToken in the first field.
    ;; $fIndex: allow for auto updating of array with index record/value.
    ;; $vDelToken: allowing for special case. (where empty string is valid data)
EndFunc
---

There might already be a topic on this(suggestion). But I'm not aware of one.

Edited by MvGulik

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites
Spiff59

This loop trims an if/else comparison and one of the optional for/next loops, at the expense of making the subtraction operation mandatory. Might run a tad faster?

$iSubItems -= 1
    For $a = 0 to $iUpper - 1
        If $a = $iElement then
            $passed = 1
        Else
            For $b = 0 to $iSubItems
                $avNewArray[$a - $passed][$b] = $avArray[$a][$b]
            Next
        EndIf
    Next

Edit: Added a one-time decrement to $iSubItems prior to the loop eliminating the subtraction operation for each element. Might trim off a few more milliseconds when processing a large array?

Or maybe since you're ByRef'ing the array, trade in the $passed variable, the temp array, the tests of $iElement, the loops to copy subitems for elements prior to the target element, and the final array copy, for one ReDim()?

Func _ArrayDelete2D(ByRef $avArray, $iElement)
    If (Not IsArray($avArray)) Then
        SetError(1)
        Return ""
    EndIf

    ; We have to define this here so that we're sure that $avArray is an array
    ; before we get it's size.
    $iUpper = UBound($avArray)    ; Size of original array

    ; If the array is only 1 element in size then we can't delete the 1 element.
    If $iUpper = 1 Then
        SetError(2)
        Return ""
    EndIf

    $iSubItems= Ubound($avArray, 2) - 1
    For $a = $iElement + 1 to $iUpper - 1
        For $b = 0 to $iSubItems
            $avArray[$a - 1][$b] = $avArray[$a][$b]
        Next
    Next
    Redim $avArray[$iUpper][$iSubItems + 1]
    Return 1
EndFunc

I didn't run any benchmarks, but I would think this would be faster when deleting elements near the top of the array, and much faster when deleting elements farther in?

Edit2: Hey! I just looked at <Array.au3> (thinking a 1D _ArrayDelete() may need some cleanup) and it already does 2D arrays! I just recreated what's already in there, almost verbatim. Am feeling a bit foolish now!

Edited by Spiff59

Share this post


Link to post
Share on other sites
MvGulik

Wow, I barely remember writing this... I've learned so much since then :blink: But, since it's already built in I don't think I'll bother fixing it..

Huh ... Oops. I mistook this topic for a recent one while searching/browsing some old topics. ;)

"Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions."
"The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014)

"Believing what you know ain't so" ...

Knock Knock ...
 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×