Jump to content

Associative Array functions


Nutster
 Share

Recommended Posts

Reading this I find the idea very charming... wondered about this when beginning with AutoIt but relatively fast lost that wonder again... but thinking about it, might it be more efficient just to create corresponding SQLite functions and let the DB handle all the performance stuff?

Edited by KaFu
Link to comment
Share on other sites

If two elements have the same hash index, then a collision occurs and the search and insertions slow down.

Now I understand. I didn't realize it allowed for duplicate keys.

I've never seen a language that does that. For example, Perl doesn't. If you use the same key, you overwrite the existing element. It assumes the developer will test if the item already exists (the "exists" operation). Or, if they need to store duplicate values, they would store an anonymous array within each AA element. (Retrieving an element would produce a reference to an array.).

I have a feeling that non-unique keys is the exception, not the norm? If so, I'd like the "create" function to accept a parm saying whether duplicate keys should be permitted. If not, then don't add 25% empty space.

But, it meets my needs as is.

I do not see the value of AssocArrayValues($aHashTable). How would it be used?

There are a few occasions (in Perl) that it's been useful to get the values of an AA. It's useful when you need it. It avoids the necessity of maintaining a separate array of all the values added to the AA. Or, getting the keys ("keys" method) and then iterating over the AA to get the values.

I think it's justified because other languages have it. Perl ("values"), scripting.dictionary ("items?"), etc.

But, you're right. It's not too important. If someone can get the keys they can get the values.

Thanks for your consideration.

Link to comment
Share on other sites

Reading this I find the idea very charming... wondered about this when beginning with AutoIt but relatively fast lost that wonder again... but thinking about it, might it be more efficient just to create corresponding SQLite functions and let the DB handle all the performance stuff?

I wanted to implement the whole thing in AutoIt, not rely on outside elements. I would have started using the Dictionary object (see earlier in the thread) before I go to all the trouble to generate a link to an external database, create a temporary table, populate it and then clean up the mess when I am done. That is just too much work for this!

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

Now I understand. I didn't realize it allowed for duplicate keys.

Not so much duplicate keys, but keys that generate the same hash value that map to the same place in the array.

Think of a classroom. If I were to quiz 25 students using a 40 point test, then more than likely a couple of students will get the same score. I then line the students up according to their marks on the test on a line with 40 spaces. There will be some gaps for the scores nobody got, and the duplicates (collisions) have to be handled some way. Let's put them in the next available spot with a higher score. How do I find a student? I figure out the student's test mark and look in the correct place in the line. If the name (key) of the student is not the one I want, check out the next student until I find the one I want. The student's name is the key, the test score is the hash value.

In this hash implementation, if you use the same key as an existing record, the old record is overwritten. Duplicate keys are not supported.

There are a few occasions (in Perl) that it's been useful to get the values of an AA. It's useful when you need it. It avoids the necessity of maintaining a separate array of all the values added to the AA. Or, getting the keys ("keys" method) and then iterating over the AA to get the values.

I think it's justified because other languages have it. Perl ("values"), scripting.dictionary ("items?"), etc.

But, you're right. It's not too important. If someone can get the keys they can get the values.

Personally, I feel that it is more useful to know the linkage between key and value, not just a list of values. So, AssocArrayKeys is in; AssocArrayValues is not.

I will spend some time writing and testing these new features today.

Take a look at Wikipedia's hash table entry for a good explanation of hash tables.

Edit: Added link to Wikipedia entry.

Edited by Nutster

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

The new Associative Array include file is in the first posting of this thread. I have added AssocArrayExist, AssocArrayDelete, AssocArrayKeys, AssocArrayVerify, and a support routine. Read the documentation at the beginning of each function for more details. Have fun! :D

Edited by Nutster
Punctuation fix. Improve explanation.

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

  • Moderators

Nutster,

Thank you for improving your UDF - I am looking for an associative array that does not need the MS Dictionary object. But I am afraid I cannot get your example to work.

Some detective work has shown that it fails every time within the AssocArrayVerify function at the "ElseIf IsInt($aArray[1][0]) = False Then Return False" stage. Thus no items can be added to the array.

Looking at the code in the AssocArrayCreate function, I see that $aArray[1][0] represents the growth factor and is set as follows:

ElseIf $nGrowth < 0 Then
; Too small
    $aArray[1][0] = 0
Else
    $aArray[1][0] = $nGrowth / 100.0

So I am not surprised that the value in question is not an integer (even the default value would be 0.5) and that the AssocArrayVerify function subsequently fails!

After commenting out this test within the AssocArrayVerify function, the example works perfectly. Did you really mean to test for an integer value for the growth factor within the function - or am I missing something else?

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Nutster,

Some detective work has shown that it fails every time within the AssocArrayVerify function at the "ElseIf IsInt($aArray[1][0]) = False Then Return False" stage. Thus no items can be added to the array.

So I am not surprised that the value in question is not an integer (even the default value would be 0.5) and that the AssocArrayVerify function subsequently fails!

After commenting out this test within the AssocArrayVerify function, the example works perfectly. Did you really mean to test for an integer value for the growth factor within the function - or am I missing something else?

M23

Ah, it was meant to be IsFloat, not IsInt at that stage. I will fix it shortly. :D Edited by Nutster

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

Ok that should do it. Check out the first posting of this thread for the files.

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

  • Moderators

Nutster,

Fixed. Thanks again for the UDF.

One question: why do hash tables work best with a prime number of items?

Forget it - read up about hash tables and now know more than I want to!

M23

Edited by Melba23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

I will spend some time writing and testing these new features today.

Thanks. When you worked on this a couple years ago you said you might convert it to a DLL (speed improvement?). If you ever have time to do that it would be nice. I think your UDF is suitable to be included with AutoIT. If it was a DLL maybe it would improve the odds?

BTW: Something changed with the "assign" function. I used to specify a growth of "0" (because I'm creating a hash from an array of fixed information, like control names, IDs, etc. I know it's not going to grow.). Now when I use 0 the "create" function works. But, the "get" function returns boolean False.

It seems to have something to do with the last few lines which call Rehash_Grow. Is it trying to grow the hash with every call to "assign?"

Thanks.

Link to comment
Share on other sites

Thanks. When you worked on this a couple years ago you said you might convert it to a DLL (speed improvement?). If you ever have time to do that it would be nice. I think your UDF is suitable to be included with AutoIT. If it was a DLL maybe it would improve the odds?

BTW: Something changed with the "assign" function. I used to specify a growth of "0" (because I'm creating a hash from an array of fixed information, like control names, IDs, etc. I know it's not going to grow.). Now when I use 0 the "create" function works. But, the "get" function returns boolean False.

It seems to have something to do with the last few lines which call Rehash_Grow. Is it trying to grow the hash with every call to "assign?"

Thanks.

I still haven't ported the code to C++ for a DLL. I have yet to read the DLL plug-in format recently.

Ok, the bug is fixed. When I changed the IsInt in the check for Associative Arrays to IsFloat, I didn't realize this would mean it would not properly recognize integer growth rates. See the first posting of this thread for the update.

David Nuttall
Nuttall Computer Consulting

An Aquarius born during the Age of Aquarius

AutoIt allows me to re-invent the wheel so much faster.

I'm off to write a wizard, a wonderful wizard of odd...

Link to comment
Share on other sites

  • 9 months later...

I'm fairly new to AutoIt, but I've been using it for the better part of two years (I was introduced to it around July/August 2008) and I've been figuring it out largely on my own with the help file. I'm hoping someone can help me figure this part out.

I'm having issues with the AssocArrayGet() function. I've run all the others and the array is getting created and variables are being assigned, but I can't retrieve them.

Here's the problematic code:

Global $dlURL, $programURL
$arrayCreate = AssocArrayCreate($dlURL,number($numberOfFiles))
ConsoleWrite("Array Created: " & $arrayCreate & @CR)
For $i = 1 to $numberOfFiles Step 1
    $progName = $urls[$i][0]
    $progURL = $urls[$i][1]
    $assign = AssocArrayAssign($dlURL,$progName,$progURL)
    ConsoleWrite("Var Assigned: " & $assign & @CR)
    $verify = AssocArrayVerify($dlURL)
    ConsoleWrite("Array Verified as Associative: " & $verify & @CR)
    $key = AssocArrayExists($dlURL,$progName)
    ConsoleWrite("Key Exists: " & $key & @CR)
    $porgramURL = AssocArrayGet($dlURL,$progName)
    ConsoleWrite("URL: " & $programURL & @CR)
    ConsoleWrite("Program Name: " & $progName & @CR)
    ConsoleWrite("URL: " & $progURL & @CR)
Next
$arraySave = AssocArraySave($dlURL,"D:\AutoIt Scripts\dlURL.txt")
ConsoleWrite("File Saved: " & $arraySave & @CR)

And its output:

>"C:\Program Files (x86)\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /run /prod /ErrorStdOut /in "D:\AutoIt Scripts\TS Software\ts_download.au3" /autoit3dir "C:\Program Files (x86)\AutoIt3" /UserParams

+>15:13:06 Starting AutoIt3Wrapper v.2.0.1.24 Environment(Language:0409 Keyboard:00000409 OS:WIN_7/ CPU:X64 OS:X64)

>Running AU3Check (1.54.19.0) from:C:\Program Files (x86)\AutoIt3

+>15:13:06 AU3Check ended.rc:0

>Running:(3.3.6.0):C:\Program Files (x86)\AutoIt3\autoit3_x64.exe "D:\AutoIt Scripts\TS Software\ts_download.au3"

Array Created: True

Var Assigned: True

Array Verified as Associative: True

Key Exists: True

URL:

Program Name: Firefox

URL: http://releases.mozilla.org/pub/mozilla.org/firefox/releases/3.6.3/win32/en-US/Firefox%20Setup%203.6.3.exe

Var Assigned: True

Array Verified as Associative: True

Key Exists: True

URL:

Program Name: Thunderbird

URL: http://releases.mozilla.org/pub/mozilla.org/thunderbird/releases/3.0.4/win32/en-US/Thunderbird%20Setup%203.0.4.exe

Var Assigned: True

Array Verified as Associative: True

Key Exists: True

URL:

Program Name: Winamp

URL: http://download.nullsoft.com/winamp/client/winamp5572_full_emusic-7plus_en-us.exe

Var Assigned: True

Array Verified as Associative: True

Key Exists: True

URL:

Program Name: Winamp Pro

URL: http://download.nullsoft.com/winamp/client/winamp5572_pro_en-us.exe

File Saved: True

+>15:13:10 AutoIT3.exe ended.rc:0

>Exit code: 0 Time: 5.299

Any ideas? I've been messing with for 2-3 hours now and it still isn't making sense what's not working... :)

EDIT: I also realize this isn't a "General Support" area, but it seemed appropriate at the time as it's directly related with the functions created here. :(

Edited by ahwm
Link to comment
Share on other sites

  • Moderators

ahwm,

You are not going to like this: :)

From your posted code:

$porgramURL = AssocArrayGet($dlURL,$progName)

ConsoleWrite("URL: " & $programURL & @CR)

If you correct the spelling it works perfectly for me. :(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

How did I miss that? *bangs head on desk* :(

A practice that you should get into the habit of is putting this line at the beginning of your code:

opt("MustDeclareVars",1)

This makes you declare (with Global or Local) each variable before you can use it. This problem would have been caught in a few seconds.

Otherwise, you can run: Au3Check.exe your_program.au3

You would see a warning message for all variables not declared or created yet.

-John

Link to comment
Share on other sites

  • 1 year later...

Very good :graduated:

I know I am bringing up an old thread but I made a function using what was already supplied to do a dump of the array.

#cs
    Function:  AssocArrayDump
    Author:  Shane Thompson
    Purpose:  Dumps the contents of the array
    Parameters:
    $aArray:  The array containing an associative array.  It could be partially populated already.
    Return value:  No return value
#ce
Func AssocArrayDump(ByRef $aArray)
    $aKeys = AssocArrayKeys($aArray)
    ConsoleWrite(">StartOfDump" & @CRLF)
    For $I = 0 To UBound($aKeys) - 1
        ConsoleWrite("> " & $aKeys[$I] & " =>   " & AssocArrayGet($aArray, $aKeys[$I]) & @CRLF)
    Next
    ConsoleWrite(">EndOfDump" & @CRLF)
    return
EndFunc     ;==>AssocArrayDump

Works good for me ;)

[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:

%programfiles%/AutoIt3/autoit3.chm
Link to comment
Share on other sites

  • 1 year later...

Nutster,

I love this code thank you....

The only thing that I have been unsuccessful in accomplishing is ....

When saving the file off I would like to be able to SORT it...

--- I am sure it is because I AM new to programming but ... Any help would be much appreciated...

I tried this in varrious parts of my program and yours... but again ... i am a NOOB.

http://www.autoitscript.com/autoit3/docs/libfunctions/_ArraySort.htm

Thank ya ... ANYONE that can help..

jason

Link to comment
Share on other sites

  • Moderators

JasonSiegrist,

Welcome to the Autoit forum. :)

Does this do what you want? :huh:

#include <Array.au3>
#include <AssocArrays.au3>

Global $aArray

; Create assoc array
AssocArrayCreate($aArray, 7)

; Fill assoc array
AssocArrayAssign($aArray, "Fred", 1)
AssocArrayAssign($aArray, "Tom", 2)
AssocArrayAssign($aArray, "Dick", 3)
AssocArrayAssign($aArray, "Harry", 4)

; Generate list of keys
$aList = AssocArrayKeys($aArray)

; Display it
_ArrayDisplay($aList, "Unsorted")

; Sort it
_ArraySort($aList)

; Display sorted list
_ArrayDisplay($aList, "Sorted")

If not, can you explain exactly what it is that you want to sort. ;)

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Pity there isn't a 'sort' method. Nice example Melba23, I hope JasonSiegrist is aware that the sorted array can't be used with the UDF anymore.

UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Link to comment
Share on other sites

Thank you both...

I am using this function to collect data ... and I am just looking for an easy way to sort the out put... and i want order the output by the 1st column assending... on save to the file.

I was playing with the UDF and trying to see where I could sort it on save ... but I have had no luck.

"Perch", 105

"Puffer", 185

"Crystal", 1

"Crab", 27

"Codex", 1

"Prawn", 3

"Nautilus", 29

"Desert", 69

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...