AutoHotkey Tip of the Week: A Look at the New Switch/Case Command

In the DateStampConvert.ahk Script, Rather than Using a Series of If-Else Statements (or the Ternary Operator), the New Switch Command Sets Up Case Statements for Alternative Results—Plus, Easily Add Conversions for Spanish, German, French, and Italian Date Formats

Over a year ago, I used a cascading series of the ternary operators to convert English text month names into their numeric values within a single function (“Use the Ternary Operator to Create Conditional Case Statements or Switches“). The ternary operator shortcut acts as If-Else statements in abbreviated form.

DateConvertSend
In the DateStampConvert.ahk script, a technique similar to Switch/Case statements converts the name of a month into its corresponding numeric value.

Since the DateTime stamp requires a numeric string (e.g. yyyymmdd ⇒ 20200115), any month found in text form must convert into its numeric value. The DateStampConvert.ahk script uses the MonthConvert(month) function to match the text month abbreviation to the corresponding numeral:

MonthConvert(month)
{
  Global NewMonth
  NewMonth := InStr(month, "jan") ? "01"
    : InStr(month, "feb") ? "02"
    : InStr(month, "mar") ? "03"
    : InStr(month, "apr") ? "04"
    : InStr(month, "may") ? "05"
    : InStr(month, "jun") ? "06"
    : InStr(month, "jul") ? "07"
    : InStr(month, "aug") ? "08"
    : InStr(month, "sep") ? "09"
    : InStr(month, "oct") ? "10"
    : InStr(month, "nov") ? "11"
    : InStr(month, "dec") ? "12"
    :"Not found!"
}

Note: Using the month name abbreviation (the first three letters) works for both the long-form of the month name (e.g. January) as well as the short-form (e.g. Jan).

One reader noted that the above set of ternary operators looks a lot like the Case Statements found in other programming languages. At the time, this cascading sequence represented my best shot at replicating a Case statement, but, as of September 2019, AutoHotkey now includes a new Switch command which allows mutually exclusive Case statements:

Switch [SwitchValue]
{
Case CaseValue1:
    Statements1
Case CaseValue2a, CaseValue2b:
    Statements2
Default:
    Statements3
}

The Switch Command offers greater flexibility than cascading ternary operators with simpler syntax than a series of If-Else statements. In those situations where you need to pick one out of a number of alternatives, the Switch command sets up a structure for making that selection.

Note: Since AutoHotkey only recently added the Switch/Case command, you must update AutoHotkey to the current version (November 24, 2019). Otherwise, AutoHotkey won’t recognize the command.

Converting the original MonthConvert() function to the new Switch command yields a similar looking list:

MonthConvert(month)
{
  Switch
  {
    Case InStr(month, "jan"): Return "01"
    Case InStr(month, "feb"): Return "02"
    Case InStr(month, "mar"): Return "03"
    Case InStr(month, "apr"): Return "04"
    Case InStr(month, "may"): Return "05"
    Case InStr(month, "jun"): Return "06"
    Case InStr(month, "jul"): Return "07"
    Case InStr(month, "aug"): Return "08"
    Case InStr(month, "sep"): Return "09"
    Case InStr(month, "oct"): Return "10"
    Case InStr(month, "nov"): Return "11"
    Case InStr(month, "dec"): Return "12"
  }
}

It doesn’t get much easier than that.

Notable Features of the Switch Command

Library Benefits

I found that the new syntax made setting up a lookup table of values easier by eliminating the need to carefully track the multiple If-Else statements. I don’t know that it works any better or faster, but the framework makes understanding, implementation, and changing the conditions simpler for the user. A few basic rules:

  1. A command statement can appear either on the same line as the Case statement (all one line) or start on the next line—including any number of command statements.
  2. Unlike multiple line If-Else statements, Case statements do not require curly brackets to enclose multiple command statement lines. (No need to keep track of curly brackets.)
  3. Up to 20 matching expression values (separated by commas) can appear after the Case command but before the closing colon. These values may come in the form of text, numbers, variables, or functions. The delimiting commas act in the same manner as a logical OR operator between each value (OR or ||) in an If-Else statement.
  4. The Switch-Case condition can either match an optional SwitchValue expressed in the Switch command line (Switch [SwitchValue]) or execute the first Case statement found true.
  5. Although not explicitly stated, the Switch command likely uses Short-circuit Boolean Evaluation. That means after finding a match and executing the enclosed Case commands, AutoHotkey exits the Switch without further evaluation.
  6. It seems that you can add GoTo Labels to the Case statements to allow jumps inside the Switch block. While I haven’t thought through how to use this type of Label jump, AutoHotkey does not support this type of movement between If and Else blocks.

Using Switch SwitchValue

By adding the optional SwitchValue parameter to the MonthConvert(month) function, I eliminated the redundant use of the InStr() or SubStr(month,1,3) function in the Case statements. This shortens the code and allows the use of simple text month abbreviations without the extra function call-outs:

MonthConvert(month)
{
  Switch SubStr(month,1,3)
  { 
    Case "jan": Return "01" 
    Case "feb": Return "02"
    Case "mar": Return "03"
    Case "apr": Return "04"
    Case "may": Return "05"
    Case "jun": Return "06"
    Case "jul": Return "07"
    Case "aug": Return "08"
    Case "sep": Return "09"
    Case "oct": Return "10"
    Case "nov": Return "11"
    Case "dec": Return "12"
  }
}

This change makes it easier to modify the Switch statement when including non-English month names.

Non-English Date Formats

To construct a little more universal DateStampConvert.ahk script, I decided to include a few other languages (Spanish, German, French, and Italian) in the conversion. First, I located the target month name abbreviations on the Yale “Abbreviations of the Names of the Months” Web page.

Fortunately, many of those shortened alternative month names correspond to the English form. In order to include the varying abbreviations in the function, I inserted non-matching patterns in the appropriate Case statement:

MonthConvert(month)
{
  Switch SubStr(month,1,3)
  { 
    Case "jan","ene","jän","gen":Return "01" 
    Case "feb","fév","fev": Return "02"
    Case "mar","mär","mer": Return "03"  ; Swiss German "Merz"
    Case "apr","abr","avr": Return "04"
    Case "may","mai","mag": Return "05"
    Case "jun","jui","gui":
      If (SubStr(month,1,4) = "juil")
        Return "07"   ; French July
      Else
        Return "06"
    Case "jul","lug": Return "07"
    Case "aug","ago","aoû","aou","ag": Return "08"
    Case "sep","set": Return "09"
    Case "oct","okt","ott": Return "10"
    Case "nov": Return "11"
    Case "dec","dic","dez","déc": Return "12"
  }
}

The French language introduces a couple of problems. First, June and July in French translate to juin and juillet. The first three letters produce a conflicting identical abbreviation (jui). The French use juin and juil as abbreviations, respectively. For a variety of reasons, changing to a four-letter abbreviation would make the conversion problem more complicated. Therefore, I added a trap for those two month names:

Case "jun","jui","gui":
  If (SubStr(month,1,4) = "juil")
    Return "07" ; French July
  Else
    Return "06"

Second, the French highlight the first day of the month by calling it le premier. I don’t know to what extent they use this in their documents (i.e. le premier janvier for the first of January) but the fix for this would require an additional Regular Expression (RegEx) in the script. I think I’ll leave this change to the French.

Change to RegEx for Special Characters (äéû)

As you can see in the MonthConvert(month) function shown above, a number of abbreviations include an accent (é), umlaut (ä) or circumflex (û). For the Regular Expression to recognize these special characters, I inserted them into the script at two RegEx locations:

([[:alpha:]äéû]+)

This RegEx continuously matches any number of characters in the standard alphabet plus any of those three special characters.

*          *          *

Cover 200

The book, A Beginner’s Guide to Using Regular Expressions in AutoHotkey, covers a number of Regular Expressions (RegEx) topics introducing practical techniques for making your AutoHotkey scripts more powerful. The first chapters introduce the concept and implementation of RegEx.

  • Chapter Five discusses eliminating double words.
  • Chapter Six discusses fixing contractions with RegEx.
  • Chapter Seven shows how to swap letters or words.
  • Chapter Eight uses RegEx to extract world location information about an IP address from a Web page.
  • Chapter Nine shows you how to remove HTML tags from any document or source code.
  • Chapter Ten demonstrates how to extract Web links from Web pages.
  • Chapter Eleven offers a RegEx for verifying valid e-mail addresses with AutoHotkey.

*          *          *

Find the complete code for the DateStampConvertSwitch.ahk script at the “ComputorEdge Free AutoHotkey Scripts” page.

For more information, see “Using Regular Expressions to Convert Most Formatted Dates into DateTime Stamps.”

Click the Follow button at the top of the sidebar on the right of this page for e-mail notification of new blogs. (If you’re reading this on a tablet or your phone, then you must scroll all the way to the end of the blog—pass any comments—to find the Follow button.)

jack

This post was proofread by Grammarly
(Any other mistakes are all mine.)

(Full disclosure: If you sign up for a free Grammarly account, I get 20¢. I use the spelling/grammar checking service all the time, but, then again, I write a lot more than most people. I recommend Grammarly because it works and it’s free.)

 

 

2 thoughts on “AutoHotkey Tip of the Week: A Look at the New Switch/Case Command

  1. I am so glad switch/case has been added to the language. I have a ton of refactoring to do now! Thanks for the great examples.

    Like

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 )

Google photo

You are commenting using your Google 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