Sign in to follow this  
Followers 0
t8inevergreen

Arrays that return from the dead

4 posts in this topic

Here is a snippet that finds duplicates in a file array passed via command line and favors csv files over atom files when duplicates are found.

The issue I am having is the script returns the array to its original state after a duplicate is deleted.

This event happens sometime after ArrayClean is called from fMonth. The array maintains the deletion while in the ArrayClean function, but once fMonth continues to check for duplicates the array is returned to its original state.

It's probably something dead simple, but my eyes have looked at this snippet for far to long to be of any further use.

Many Thanks

#include <Array.au3>

;Begin with simulated array container of a list of files passed via command line.
;For the sake of readability and fast testing, this array is pre-sorted. In the real script, I will use ArrayNaturalSort

Dim $CMDLine1[38] = ["R:\2009-1-1.atom", "R:\2009-1-2.atom", "R:\2009-1-2.csv", "R:\2009-1-3.atom", "R:\2009-1-4.atom", "R:\2009-1-5.atom", "R:\2009-1-6.atom", "R:\2009-1-7.atom", "R:\2009-1-8.atom", "R:\2009-1-9.atom", "R:\2009-1-9.csv", "R:\2009-1-10.atom", "R:\2009-1-10.csv", "R:\2009-1-11.atom", "R:\2009-1-11.csv", "R:\2009-1-12.atom", "R:\2009-1-13.atom", "R:\2009-1-14.atom", "R:\2009-1-15.atom", "R:\2009-1-16.atom", "R:\2009-1-17.atom", "R:\2009-1-18.atom", "R:\2009-1-19.atom", "R:\2009-1-20.atom", "R:\2009-1-21.atom", "R:\2009-1-22.atom", "R:\2009-1-23.atom", "R:\2009-1-24.atom", "R:\2009-1-25.atom", "R:\2009-1-26.atom", "R:\2009-1-27.atom", "R:\2009-1-27.csv", "R:\2009-1-28.atom", "R:\2009-1-29.atom", "R:\2009-1-30(1).csv", "R:\2009-1-30.atom", "R:\2009-1-30.csv", "R:\2009-1-31.atom"]
fMonth($CMDLine1)

Func fMonth($CMDLine1)
    Global $ArrayMax = UBound($CMDLine1)-1
    For $fm = 0 To $ArrayMax
        If $fm+1 <= $ArrayMax Then
        ;If the file name of $CMDLine1[$fm] == $CMDLine1[$fm+1] then call ArrayClean
            If fStrip(fStrip($CMDLine1[$fm], "\", 2), ".||(", 1) == fStrip(fStrip($CMDLine1[$fm + 1], "\", 2), ".||(", 1) Then ArrayClean($CMDLine1, $fm)
        Else
            ExitLoop
        EndIf
    Next
    _ArrayDisplay($CMDLine1)
    
;========All code in this function beyond this point is unimportant===========
    
    $rSelect = $CMDLine1[Random(1, $CMDLine1[0], 1)]
    $rSplit = StringSplit(fStrip($rSelect, "\", 2), "-")
    $rMonth = $rSplit[2]
    Dim $Month, $errFlag1, $errFlag2
    Switch $rMonth
        Case 1
            $Month = "Jan"
        Case 2
            $Month = "Feb"
        Case 3
            $Month = "Mar"
        Case 4
            $Month = "Apr"
        Case 5
            $Month = "May"
        Case 6
            $Month = "Jun"
        Case 7
            $Month = "Jul"
        Case 8
            $Month = "Aug"
        Case 9
            $Month = "Sep"
        Case 10
            $Month = "Oct"
        Case 11
            $Month = "Nov"
        Case 12
            $Month = "Dec"
    EndSwitch
    Return StringLeft($rSelect, StringInStr($rSelect, "\", 0, -1)) & $Month & " " & $rSplit[1] & ".csv"
EndFunc  ;==>fMonth

Func fStrip($fPathInStrip, $char, $set)

;This is a string processor that returns all characters before or after ($set) a certain character ($char)
;$char can be conditional, ie IF the string contains this character, then use it as the $char, else use the other provided character
;|| signifies the conditional. So, ".||(" translates into "If the string has "(" then use it as $char, else use "." as $char"

    $fStripSplit = StringSplit($char, "||", 1)
    Switch $set
        Case 1
            If @error <> 1 Then
                If StringInStr($fPathInStrip, $fStripSplit[2]) <> 0 Then 
                    Return StringLeft($fPathInStrip, (StringInStr($fPathInStrip, $fStripSplit[2], 2, -1) - 1))
                Else
                    Return fStrip($fPathInStrip, $fStripSplit[1], 1)
                endif
            Else
                Return StringLeft($fPathInStrip, (StringInStr($fPathInStrip, $char, 2, -1) - 1))
            EndIf
        Case 2
            If @error <> 1 Then
                If StringInStr($fPathInStrip, $fStripSplit[2]) <> 0 Then 
                    Return StringRight($fPathInStrip, StringLen($fPathInStrip) - StringInStr($fPathInStrip, $fStripSplit[2], 2, +1))
                Else
                    Return fStrip($fPathInStrip, $fStripSplit[1], 1)
                Endif
            Else
                Return StringRight($fPathInStrip, StringLen($fPathInStrip) - StringInStr($fPathInStrip, $char, 2, -1))
            EndIf
    EndSwitch
EndFunc  ;==>fStrip

Func ArrayClean($CMDLine1, $idx)
    Dim $level = 0, $multis = $idx & ";"
    While 1
        $level += 1
        If fStrip(fStrip($CMDLine1[$idx+$level], "\", 2), ".||(", 1) == fStrip(fStrip($CMDLine1[$idx], "\", 2), ".||(", 1) then
            $multis &= $idx + $level&";"
        Else
            ExitLoop
        EndIf
    WEnd
    $MultiList = StringSplit($multis, ";")
    $MultiList[0] -= 1
    
    If fileExt($CMDLine1[$MultiList[$MultiList[0]]]) == "csv" then 
        For $ac = 1 to $MultiList[0]-1
            $ArrayMax = _ArrayDelete($CMDLine1, $MultiList[$ac])
        Next
    Else
        For $ac = 2 to $MultiList[0]
            $ArrayMax = _ArrayDelete($CMDLine1, $MultiList[$ac])
        Next
    EndIf
EndFunc  ;==>ArrayClean

Func fileExt($fPathInExt)
;Returns the extension of a file
    Return fStrip($fPathInExt, ".", 2)
EndFunc  ;==>fileExt

Share this post


Link to post
Share on other sites



Here is a snippet that finds duplicates in a file array passed via command line and favors csv files over atom files when duplicates are found.

The issue I am having is the script returns the array to its original state after a duplicate is deleted.

This event happens sometime after ArrayClean is called from fMonth. The array maintains the deletion while in the ArrayClean function, but once fMonth continues to check for duplicates the array is returned to its original state.

It's probably something dead simple, but my eyes have looked at this snippet for far to long to be of any further use.

Many Thanks

#include <Array.au3>
 
;Begin with simulated array container of a list of files passed via command line.
;For the sake of readability and fast testing, this array is pre-sorted. In the real script, I will use ArrayNaturalSort
 
 Dim $CMDLine1[38] = ["R:\2009-1-1.atom", "R:\2009-1-2.atom", "R:\2009-1-2.csv", "R:\2009-1-3.atom", "R:\2009-1-4.atom", "R:\2009-1-5.atom", "R:\2009-1-6.atom", "R:\2009-1-7.atom", "R:\2009-1-8.atom", "R:\2009-1-9.atom", "R:\2009-1-9.csv", "R:\2009-1-10.atom", "R:\2009-1-10.csv", "R:\2009-1-11.atom", "R:\2009-1-11.csv", "R:\2009-1-12.atom", "R:\2009-1-13.atom", "R:\2009-1-14.atom", "R:\2009-1-15.atom", "R:\2009-1-16.atom", "R:\2009-1-17.atom", "R:\2009-1-18.atom", "R:\2009-1-19.atom", "R:\2009-1-20.atom", "R:\2009-1-21.atom", "R:\2009-1-22.atom", "R:\2009-1-23.atom", "R:\2009-1-24.atom", "R:\2009-1-25.atom", "R:\2009-1-26.atom", "R:\2009-1-27.atom", "R:\2009-1-27.csv", "R:\2009-1-28.atom", "R:\2009-1-29.atom", "R:\2009-1-30(1).csv", "R:\2009-1-30.atom", "R:\2009-1-30.csv", "R:\2009-1-31.atom"]
 fMonth($CMDLine1)
 
 Func fMonth($CMDLine1)
     Global $ArrayMax = UBound($CMDLine1)-1
     For $fm = 0 To $ArrayMax
         If $fm+1 <= $ArrayMax Then
        ;If the file name of $CMDLine1[$fm] == $CMDLine1[$fm+1] then call ArrayClean
             If fStrip(fStrip($CMDLine1[$fm], "\", 2), ".||(", 1) == fStrip(fStrip($CMDLine1[$fm + 1], "\", 2), ".||(", 1) Then ArrayClean($CMDLine1, $fm)
         Else
             ExitLoop
         EndIf
     Next
     _ArrayDisplay($CMDLine1)
     
;========All code in this function beyond this point is unimportant===========
     
     $rSelect = $CMDLine1[Random(1, $CMDLine1[0], 1)]
     $rSplit = StringSplit(fStrip($rSelect, "\", 2), "-")
     $rMonth = $rSplit[2]
     Dim $Month, $errFlag1, $errFlag2
     Switch $rMonth
         Case 1
             $Month = "Jan"
         Case 2
             $Month = "Feb"
         Case 3
             $Month = "Mar"
         Case 4
             $Month = "Apr"
         Case 5
             $Month = "May"
         Case 6
             $Month = "Jun"
         Case 7
             $Month = "Jul"
         Case 8
             $Month = "Aug"
         Case 9
             $Month = "Sep"
         Case 10
             $Month = "Oct"
         Case 11
             $Month = "Nov"
         Case 12
             $Month = "Dec"
     EndSwitch
     Return StringLeft($rSelect, StringInStr($rSelect, "\", 0, -1)) & $Month & " " & $rSplit[1] & ".csv"
 EndFunc ;==>fMonth
 
 Func fStrip($fPathInStrip, $char, $set)
 
;This is a string processor that returns all characters before or after ($set) a certain character ($char)
;$char can be conditional, ie IF the string contains this character, then use it as the $char, else use the other provided character
;|| signifies the conditional. So, ".||(" translates into "If the string has "(" then use it as $char, else use "." as $char"
 
     $fStripSplit = StringSplit($char, "||", 1)
     Switch $set
         Case 1
             If @error <> 1 Then
                 If StringInStr($fPathInStrip, $fStripSplit[2]) <> 0 Then 
                     Return StringLeft($fPathInStrip, (StringInStr($fPathInStrip, $fStripSplit[2], 2, -1) - 1))
                 Else
                     Return fStrip($fPathInStrip, $fStripSplit[1], 1)
                 endif
             Else
                 Return StringLeft($fPathInStrip, (StringInStr($fPathInStrip, $char, 2, -1) - 1))
             EndIf
         Case 2
             If @error <> 1 Then
                 If StringInStr($fPathInStrip, $fStripSplit[2]) <> 0 Then 
                     Return StringRight($fPathInStrip, StringLen($fPathInStrip) - StringInStr($fPathInStrip, $fStripSplit[2], 2, +1))
                 Else
                     Return fStrip($fPathInStrip, $fStripSplit[1], 1)
                 Endif
             Else
                 Return StringRight($fPathInStrip, StringLen($fPathInStrip) - StringInStr($fPathInStrip, $char, 2, -1))
             EndIf
     EndSwitch
 EndFunc ;==>fStrip
 
 Func ArrayClean($CMDLine1, $idx)
     Dim $level = 0, $multis = $idx & ";"
     While 1
         $level += 1
         If fStrip(fStrip($CMDLine1[$idx+$level], "\", 2), ".||(", 1) == fStrip(fStrip($CMDLine1[$idx], "\", 2), ".||(", 1) then
             $multis &= $idx + $level&";"
         Else
             ExitLoop
         EndIf
     WEnd
     $MultiList = StringSplit($multis, ";")
     $MultiList[0] -= 1
     
     If fileExt($CMDLine1[$MultiList[$MultiList[0]]]) == "csv" then 
         For $ac = 1 to $MultiList[0]-1
             $ArrayMax = _ArrayDelete($CMDLine1, $MultiList[$ac])
         Next
     Else
         For $ac = 2 to $MultiList[0]
             $ArrayMax = _ArrayDelete($CMDLine1, $MultiList[$ac])
         Next
     EndIf
 EndFunc ;==>ArrayClean
 
 Func fileExt($fPathInExt)
;Returns the extension of a file
     Return fStrip($fPathInExt, ".", 2)
 EndFunc ;==>fileExt
I haven't really studied your code but I notice that you are passing the array to functions by value. The function deals with a copy of the function and outside of the function the original array is unchanged. I know that you use the same name in your function as the Global name, but I think that a parameter passed to a function is treated as Local inside the function. If that is your problem then the solution is quite simple.

Either

Just change your functions like this

Change

Func ArrayClean($CMDLine1, $idx)

to

Func ArrayClean(ByRef $CMDLine1, $idx)

for example.

OR

remove the parameter so that the global variable is used,

change

Func ArrayClean($CMDLine1, $idx)

to

Func ArrayClean($idx)


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Ah! That's exactly what it was

Autoit Help File:

The ByRef keyword is optional and means: (1) the parameter must a variable, and (2) the original variable is linked to the parameter, so that any changes to the parameter inside the function, would affect the original variable as well.

Thank you very much Martin, you're the best

Share this post


Link to post
Share on other sites

#include <Array.au3>

;Begin with simulated array container of a list of files passed via command line.
;For the sake of readability and fast testing, this array is pre-sorted. In the real script, I will use ArrayNaturalSort

Dim $CMDLine1[38] = ["R:\2009-1-1.atom", "R:\2009-1-2.atom", "R:\2009-1-2.csv", _
                     "R:\2009-1-3.atom", "R:\2009-1-4.atom", "R:\2009-1-5.atom", _
                     "R:\2009-1-6.atom", "R:\2009-1-7.atom", "R:\2009-1-8.atom", _
                     "R:\2009-1-9.atom", "R:\2009-1-9.csv", "R:\2009-1-10.atom", _
                     "R:\2009-1-10.csv", "R:\2009-1-11.atom", "R:\2009-1-11.csv", _
                     "R:\2009-1-12.atom", "R:\2009-1-13.atom", "R:\2009-1-14.atom", _
                     "R:\2009-1-15.atom", "R:\2009-1-16.atom", "R:\2009-1-17.atom", _
                     "R:\2009-1-18.atom", "R:\2009-1-19.atom", "R:\2009-1-20.atom", _
                     "R:\2009-1-21.atom", "R:\2009-1-22.atom", "R:\2009-1-23.atom", _
                     "R:\2009-1-24.atom", "R:\2009-1-25.atom", "R:\2009-1-26.atom", _
                     "R:\2009-1-27.atom", "R:\2009-1-27.csv", "R:\2009-1-28.atom", _
                     "R:\2009-1-29.atom", "R:\2009-1-30(1).csv", "R:\2009-1-30.atom", _
                     "R:\2009-1-30.csv", "R:\2009-1-31.atom"]


Dim $Array = fMonth($CMDLine1)
If IsArray($Array) Then _ArrayDisplay($Array)

Func fMonth($avArr)
    Local $i, $j = 1
    Local $avTmp[UBound($avArr)][2], $aMatch
    Local $avRet[1]
    
    For $i = 0 To UBound($avArr)-1
        $aMatch = StringRegExp($avArr[$i], '(.*\.)(.*)', 1)
        $avTmp[$i][0] = $aMatch[0]
        $avTmp[$i][1] = $aMatch[1]
    Next
    
    $i = 0
    
    While $i < UBound($avTmp, 1)-1
        
        $j = _ArraySearch($avTmp, $avTmp[$i][0], $j, 0, 0, 0, 1)
       
        If $j <> -1 Then
            If $avTmp[$i][1] = '.csv' Then
                _ArrayDelete($avTmp, $j)
            Else
                _ArrayDelete($avTmp, $i)
            EndIf
        Else
            $i += 1
            $j = $i + 1
        EndIf
    WEnd
    
    For $i = 0 To UBound($avTmp)-1
        ReDim $avRet[$i+1]
        $avRet[$i] = $avTmp[$i][0] & $avTmp[$i][1]
    Next
    
    Return $avRet
        
EndFunc

If you're still interested.

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  
Followers 0