t8inevergreen Posted March 14, 2009 Posted March 14, 2009 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 expandcollapse popup#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
martin Posted March 14, 2009 Posted March 14, 2009 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 expandcollapse popup#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.
t8inevergreen Posted March 15, 2009 Author Posted March 15, 2009 Ah! That's exactly what it wasAutoit 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
Authenticity Posted March 15, 2009 Posted March 15, 2009 expandcollapse popup#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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now