The AutoHotkey “For Key [, Value] in Expression” Loop for Associative Arrays

The Standard AutoHotkey Loop Command Works Great for Incremental Series, But the For Key [, Value] in Expression Object Loop Offers Unique Flexibility for Associative Arrays

In my last blog, I introduced associative arrays to the InstantHotkeyArrays.ahk script for solving the connection problem between the Instant Hotkey combination and the insertion text. It works brilliantly—although novice AutoHotkey users might experience a slight learning curve.

On the downside of associative arrays, the standard AutoHotkey Loop command may not provide the access you need to all of the array items. Fortunately, AutoHotkey provides a command specifically for use with Objects such as true arrays: For Key [, Value] in Expression.

Beginner's Guide to AutoHotkeyIf you’re new to AutoHotkey with little or no scripting experience, then this blog may venture a little too far into the weeds. I don’t like to discourage new users with more involved concepts because the journey into Windows scripting is well worthwhile. Most find it easy to get started with AutoHotkey with many simple-to-implement tools. However, it takes a little time to understand the nuances of the more advanced techniques. I recommend that AutoHotkey noobies start with the fundamentals such as found in the “Introduction to AutoHotkey: A Review and Guide for Beginners” page. You’ll obtain immediate, rewarding results with basic AutoHotkey. Then, as your comfort with scripting increases, introduce yourself to more of AutoHotkey’s power with some of the slightly elevated topics.

The For-loop Command

The For-loop command—which works with both simple and associative arrays, although not pseudo-arrays—increments through an entire simple or associative array in alphanumeric sort order:

For index, element in InstantHotkey 
     MsgBox % "Element number " . index . " is " . element

This snippet of code displays each value (element) of the array InstantHotkey[] for each key (index) as the loop increments through all assigned array items.

Tip: You can use any variable names for index and element as long as they don’t interfere with any other variable names in the script. If you want to isolate the For-loop variable names, then place the command inside a function, thus making all variables local.

As an example of For-loop sort order, I ran InstantHotkeyArrays.ahk and set up three Instant Hotkey combinations with associated sample text, then ran a For-loop routine to reveal the contents of InstantHotkey[]:

InstantHotkey[1] ⇒ "^!o"
InstantHotkey[2] ⇒ "^!n" 
InstantHotkey[3]⇒ "^!b" 
InstantHotkey["^!b"] ⇒ "Text for ^!B" 
InstantHotkey["^!n"] ⇒ "Text for ^!N"
InstantHotkey["^!o"] ⇒ "Text for ^!O"

The For-loop includes all active items regardless of where or when you originally assigned each array key/value pair. This command always uses an alphanumeric sort, therefore, it may not present data in the desired order.

For-loop Display Order

Note that in the above list of array items, the Hotkey combinations appear in activated order based upon the integer index, while the insertion text appears in alphabetical order by Hotkey combination. The last three array items don’t match up with the order of the first three. For use in the InstantHotkey.ahk script which matches Hotkey combinations to insertion text, the last three values come out in an inconvenient random order. The traditional Loop command array and pseudo-array techniques which increment the array index by 1 on each pass won’t work for associative arrays with non-numeric keys.

In this situation, we use a technique similar to the two-deep variable by inserting an array item as the array index of the matching array item to recall the appropriate data:

InstantHotkey[InstantHotkey[index]]

If the script uses one of the numeric indexes, this expression then returns the correct insertion text:

InstantHotkey[1] ⇒ "^!o"
InstantHotkey["^!o"] ⇒ "The text for ^!O"
InstantHotkey[InstantHotkey[1]] ⇒ "The text for ^!O"

By using this array trick, we can create a list of Hotkey combinations and the connected insertion text with the For-loop:

^F1::
HotkeyHelp := "Hotkey ⇒ Insertion Text"
For index, element in InstantHotkey
{
  If index is integer
    If element ; Hotkey not blank
      HotkeyHelp := % HotkeyHelp . "`r" . Upper(element) 
        . " ⇒ " . InstantHotkey[InstantHotkey[index]]
}
MsgBox % HotkeyHelp
Return

(AutoHotkey line continuation used to word wrap the HotkeyHelp line of code for display purposes.)

Array HotkeysSince each Instant Hotkey combination uses the GUI number as the array index, looking for an integer (If index is integer) as an index isolates each Instant Hotkey. Next, checking for a value (If element) eliminates blank Hotkeys. As the For-loop increments through the array, the routine builds a list of valid Hotkeys and insertion text by appending each to the end of HotkeyHelp. After terminating the loop, the MsgBox command displays a list of Hotkey combinations and the associated insertion text.

When using the For-loop with associative arrays, pay attention to the order in which the command recalls the elements of the array. If you store animal sounds keyed to the animal names:

Sound["Horse"] := "Neigh"
Sound["Cow"] := "Moo"
Sound["Pig"] := "Oink"

the For-loop displays items in alphabetical order based on the array key:

Sound["Cow"] := "Moo"
Sound["Horse"] := "Neigh"
Sound["Pig"] := "Oink"

You’ll find the For-loop a powerful command for recalling array data as long as you stay aware of how it works.

jack

*          *          *

Like anybody else, I have expenses and a need to make ends meet. As “Jack’s AutoHotkey Blog” increases in popularity, coding the test scripts and writing the blogs takes up more of my time. That means I’ve less time to pursue other income-earning opportunities. I don’t plan to ever move “Jack’s AutoHotkey Blog” behind a paywall, but if you think my efforts are worth a bit of your hard-earned cash, then help support my efforts by purchasing one or two of my AutoHotkey books or making a direct contribution. You may not need the references yourself, but you might know someone who can benefit from them.

Thank You,

Jack Dunning

 

 

 

 

 

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s