Sign in to follow this  
Followers 0
sshrum

Array functions I'd like see added to the ARRAY UDF

3 posts in this topic

#1 ·  Posted (edited)

Currently, the Array UDF handles single dim'ed arrays. Here are a couple of funcs I made that handle single and 2 dimension'ed arrays:

_ArrayShuffle - takes an array Byref and shuffles the row ordering

_ArrayMerge - takes 2 similar dim'ed arrays and appends one to the other, updates the # in [0],[0][0]

_ArrayFilter - full-text or column-specific searches of single or 2 dim'ed arrays, returns back an array of row contents that match

_Array2File - dumps the array out to a file, support for user defined separators

_File2Array - loads a array file into and array, looks at line 1 for dimensions and seperator

_KeySet - think of it as WriteINI for arrays, I use this to create a master variables list

_ValueGet - think of this as ReadINI for arrays, I use this to read the master variables list

Why, you ask?

I use _KeySet to create an array of key=value pairs (like an INI file) and use _ValueGet to retrieve them. Also, this way I can parse the array for a complete list of variables that are defined. I then use _Array2File to store the values to a file so after the app quits, I can use _File2Array to reload the values back in.

_ArrayMerge is great when you are dealing with a lot of arrays that you want to bring together into one. _ArrayFilter for when you only want certain data, and _ArrayShuffle...well, for when you want to mix up the contents of an array (2-dim relations are kept...basically this means it just shuffles rows)

Not really a UDF but 95% of the work is in there. Check it out and let me know if they can be improved on:

func _Array2File($aTemp, $sFilename, $iBase=1, $sSeperator="|")
    Consolewrite("(_Array2File) ")
    $iTimer = TimerInit()
    $iRows = ubound($aTemp) - $iBase
    $iCols = ubound($aTemp,2)
    if $iCols = 0 then $iCols = 1
    ConsoleWrite("[ " & $iRows & " " & $sSeperator & " " & $iCols & " ] -> Writting '" & $sFilename & "'; ")
    $fOutput = FileOpen($sFilename, 2+8)
    FileWriteLine($fOutput, $iRows & $sSeperator & $iCols)
    if $iCols = 1 then 
        For $i = $iBase to $iRows
            FileWriteLine($fOutput, $aTemp[$i])
        next        
    Else
        For $i = $iBase to $iRows
            $sLine = ""
            for $j = 0 to ($iCols - 1)
                if $j <> 0 AND $iCols > 1 then $sLine &= $sSeperator 
                $sLine &= $aTemp[$i][$j]
            Next
            FileWriteLine($fOutput, $sLine)
        next
    EndIf
    Fileclose($fOutput)
    ConsoleWrite("complete [" & Round(TimerDiff($iTimer)/1000,2) & " secs]" & @CRLF)
    return $aTemp
EndFunc

Func _ArrayFilter($aTemp, $sSearch, $iBase=1, $iCol=-1, $iCase=2)
    Consolewrite("(_ArrayFilter) ")
    $iTimer = TimerInit()
    $iRows = ubound($aTemp) - $iBase
    if $iRows = 0 then return $aTemp
    $iCols = ubound($atemp,2)
    if $iCols = 0 then 
        Dim $aTemp2[$iRows]
        $aTemp2[0] = 0
        ConsoleWrite("[ " & $iRows & " ] ")
    Else
        Dim $aTemp2[$iRows][$iCols]
        $aTemp[0][0] = 0
        ConsoleWrite("[ " & $iRows & " x " & $iCols & " ] ")
    EndIf
    Consolewrite("-> Looking for '" & $sSearch & "' ")
    if $iCol > $iCols then 
        seterror(1)
        return $aTemp2
    EndIf
    $aSearch = StringSplit($sSearch, ",")
    $iLine = 0
    $iFlag = False
    if $iCols = 0 Then
        For $i = $iBase to $iRows
            for $k = 1 to $aSearch[0]
                if stringinstr($aTemp[$i], $aSearch[$k], $iCase) then
                    $iLine += 1
                    $aTemp2[$iLine] = $aTemp[$i]
                    ExitLoop
                endif
            next
        next        
        redim $aTemp2[$iLine+1]
        $aTemp2[0] = $iLine
    Else
        if $iCol = -1 Then
            ConsoleWrite("in all fields...")
            For $i = $iBase to $iRows
                for $j = 0 to ($iCols - 1)
                    for $k = 1 to $aSearch[0]
                        if stringinstr($aTemp[$i][$j], $aSearch[$k], $iCase) then
                            $iLine += 1
                            $iFlag = true
                            ExitLoop 2
                        endif
                    next
                Next
                if $iFlag Then
                    for $j = 0 to ($iCols - 1)
                        $aTemp2[$iLine][$j] = $aTemp[$i][$j]
                    Next
                    $iFlag = False
                EndIf
            next
        Else
            ConsoleWrite("in column " & $iCol & "...")
            For $i = $iBase to $iRows
                for $k = 1 to $aSearch[0]
                    if stringinstr($aTemp[$i][$iCol], $aSearch[$k], $iCase) then
                        $iLine += 1
                        $iFlag = true
                        ExitLoop
                    endif
                next
                if $iFlag Then
                    for $j = 0 to ($iCols - 1)
                        $aTemp2[$iLine][$j] = $aTemp[$i][$j]
                    Next
                    $iFlag = False
                EndIf
            Next
        EndIf
        redim $aTemp2[$iLine+1][$iCols]
        $aTemp2[0][0] = $iLine
    EndIf   
    ConsoleWrite($iLine & " records found; complete [" & Round(TimerDiff($iTimer)/1000,2) & " secs]" & @CRLF)
    return $aTemp2
EndFunc

func _ArrayMerge (ByRef $aTemp1, $aTemp2, $iBase=1)
    Consolewrite("(_ArrayMerge) ")
    $iTimer = TimerInit()
    $iRows1 = ubound($aTemp1) - $iBase
    $iCols1 = ubound($aTemp1,2)
    $iRows2= ubound($aTemp2) - $iBase
    $iCols2 = ubound($aTemp2,2)
    If $iCols1 <> $iCols2 then 
        seterror(1)
        Exit
    endif
    ConsoleWrite("Merging " & $iRows2 & " entries with " & $iRows1 & " entries in originating array...")
    If $iCols1 = 0 Then
        $iTotal = $aTemp1[0] + $aTemp2[0]
        redim $aTemp1[$iTotal+1]
        For $i = $aTemp1[0][0] + $iBase to $iTotal
            $aTemp1[$i] = $aTemp2[$i - ($aTemp1[0] + $iBase) + 1]
        next
        $aTemp1[0] = $iTotal
    Else
        $iTotal = $aTemp1[0][0] + $aTemp2[0][0]
        redim $aTemp1[$iTotal+1][$iCols1]
        For $i = $aTemp1[0][0] + $iBase to $iTotal
            for $j = 0 to ($iCols1 - 1)
                $aTemp1[$i][$j] = $aTemp2[$i - ($aTemp1[0][0] + $iBase) + 1][$j]
            Next
        next
        $aTemp1[0][0] = $iTotal
    EndIf
    ConsoleWrite("complete [" & Round(TimerDiff($iTimer)/1000,2) & " secs]" & @CRLF)
EndFunc

Func _ArrayShuffle(ByRef $aTemp, $iBase=1)
    Consolewrite("(_ArrayShuffle) ")
    $iTimer = TimerInit()
    $iRows = UBound($aTemp) -1
    $iCols = UBound($aTemp,2)
    if $iCols = 0 then 
        ConsoleWrite("[ " & $iRows & " ] ")
        For $i = $iBase To $iRows
            $iRandom = Random($iBase,$iRows)
            $sTemp = $aTemp[$i]
            $aTemp[$i] = $aTemp[$iRandom]
            $aTemp[$iRandom] = $sTemp
        Next
    Else
        Dim $aTemp2[1][$iCols]
        ConsoleWrite("[ " & $iRows & " x " & $iCols & " ] ")
        For $i = $iBase To $iRows - $iBase
            $iRandom = Random($iBase,$iRows)
            For $j = 0 to $iCols - 1
                $aTemp2[0][$j] = $aTemp[$i][$j]
                $aTemp[$i][$j] = $aTemp[$iRandom][$j]
                $aTemp[$iRandom][$j] = $aTemp2[0][$j]
            Next
        Next
    EndIf
    ConsoleWrite("complete [" & Round(TimerDiff($iTimer)/1000,2) & " secs]" & @CRLF)
EndFunc

Func _File2Array($sFilename)
    Consolewrite("(_File2Array) ")
    $iTimer = TimerInit()
    $iSize = round(FileGetSize($sFilename)/1024/1024,2)
    $fInput = FileOpen($sFilename,0)
    $sMatrix = FileReadLine($fInput)
    $sSeperator = StringRegExpReplace($sMatrix, "[0-9]", "")
    $aMatrix = StringSplit($sMatrix, $sSeperator)
    consolewrite("[ " & $aMatrix[1] & " x " & $aMatrix[2] & " ] -> Reading '" & $sFilename & "' (" & $iSize & " megs); ")
    if $aMatrix[2] = 1 Then
        Dim $aTemp[$aMatrix[1]+1]
        $aTemp[0]=$aMatrix[1]
    Else
        Dim $aTemp[$aMatrix[1]+1][$aMatrix[2]]
        $aTemp[0][0]=$aMatrix[1]
    EndIf
    if $aMatrix[2] = 1 Then
        For $i = 1 to $aMatrix[1]
            $aTemp[$i] = FileReadLine($fInput)
        Next        
    Else
        For $i = 1 to $aMatrix[1]
            $sLine = FileReadLine($fInput)
            $aLine = StringSplit($sLine, $sSeperator)
            for $j = 1 to $aMatrix[2]
                $aTemp[$i][$j-1] = $aLine[$j]
            Next
        Next
    EndIf
    Fileclose($fInput)
    ConsoleWrite("complete [" & Round(TimerDiff($iTimer)/1000,2) & " secs]" & @CRLF)
    return $aTemp
EndFunc

func _KeySet(Byref $aTemp, $sKey, $sValue)
    for $i = 1 to $aTemp[0][0]
        if $aTemp[$i][0] = $sKey then 
            $aTemp[$i][1] = $sValue
            Return
        EndIf
    Next
    $iNext = $aTemp[0][0]+1
    ReDim $aTemp[$iNext+1][2]
    $aTemp[0][0] = $iNext
    $aTemp[$iNext][0] = $sKey
    $aTemp[$iNext][1] = $sValue
    _arraySort($aTemp,0,1,0,2,0)
EndFunc

func _ValueGet(ByRef $aTemp, $sKey)
    for $i = 1 to $aTemp[0][0]
        if $aTemp[$i][0] = $sKey then return $aTemp[$i][1]
    Next
    return
EndFunc

- Enjoy

Edited by sshrum

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Share this post


Link to post
Share on other sites



I love the features just wanted to mention I have been trying to figure out how to store an array that a helper script of mine makes into a file so that another script can grab and use that array. I tried using your array to file and file to array but for some reason its chopping out one of the items in the array..

I have an array thats looks something like : $array[1681] = blah

I stored it to a txt file and re-grabbed it and its coming back as an array with only 1680 elements instead of the 1681? Also the array I stored I had striped the $array[0] out of it that shows how many items are in the array and when I pulled the array back from the file it had that item in it again?

Love the idea, don't know if its just that I am an idiot but I can't get it to work...

Keltset


-K

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Make sure you are setting $iBase to 0 when you call the function. That way, the function knows to write the elements starting at 0. Many people use $array[0] as an index for the number of elements in the array. That is probably why the default value is set to 1.

Edited by dantay9

[font="Verdana"] [size="2"]"[/size][/font]Failure is not an option -- it comes packaged with Windows"[font="Verdana"][size="2"] Gecko Web Browser[/size][/font][font="Verdana"][size="2"], [/size][/font][font="Verdana"][size="2"]Yahtzee![/size][/font][font="Verdana"][size="2"], Toolbar Launcher (like RocketDock)[/size][/font][font="Verdana"][size="2"]Internet Blocker, Simple Calculator, Local Weather, Easy GDI+ GUI [/size][/font][font="Verdana"][size="2"]Triangle Solver, TCP File Transfer, [/size][/font][font="Verdana"][size="2"]Valuater's Autoit Wrappers[/size][/font][font="Verdana"][size="3"][size="2"][size="2"]OOP In AutoIt[/size][/size][/size][/font][font="Verdana"][size="2"][size="1"]Using Windows XP SP3, 1GB RAM, AMD Athlon Processor @ 2.1 GHzCheck me out at gadgets.freehostrocket.com[/size][/size][/font]

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