Jump to content

In-line Case (_ICase)


cyberbit
 Share

Recommended Posts

I realized that there's no easy way to do something like this on one line, inline with other commands, with native functions:

Local $msg = 4

While $msg = 4
    Local $txt, $num = Random(1, 6, 1)

    Switch $num
        Case 1
            $txt = "Number 1 was chosen!"
        Case 2
            $txt = "This is what shows for #2"
        Case 3
            $txt = "3 is a magic number."
        Case 4
            $txt = "Twas a 4"
        Case Else
            $txt = "Uh oh! I don't know about " & $num & ", sorry."
    EndSwitch

    $msg = MsgBox(5+32, "Traditional Case Method", $txt)
WEnd
Alternatively, you could use nested _Iif functions:

$num = Random(1, 6, 1)
    $msg = MsgBox(5+32, "Using _Iif", _Iif($num=1, "Number 1 was chosen!", _Iif($num=2, "This is what shows for #2", _Iif($num=3, "3 is a magic number.", _Iif($num=4, "Twas a 4", "Uh oh! I don't know about " & $num & ", sorry.")))))
but that can get really confusing quickly.

 

Thus, I wrote this small function that acts like an in-line case statement. It returns values based on other values (case-like) from delimited strings.

 

Usage:

_ICase(Random(1, 6, 1), "1|2|3|4", "Number 1 was chosen!|This is what shows for #2|3 is a magic number.|Twas a 4", "Uh oh! I don't know about %s, sorry.")
The last parameter is an "else" value. It is fed to a StringFormat, so put %s where you want to see the value.

 

If the number of values is greater than the number of given returns, nulls ("") are appended to the end of the returns to make up for the difference. Not ideal (read, I need to improve this), but correct syntax will avoid the issue.  ;)

 

_ICase.au3

 

-cb

Edited by cyberbit

_ArrayConcatenate2D · Aero Flip 3D · EPOCH (destroy timestamps) · File Properties Modifier · _GetFileType · UpdateEngine<new> · In-line Case (_ICase) <new>

[hr]

50% of the time, it works all the time. -PezoFaSho

Link to comment
Share on other sites

An interesting concept at least.

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

I do it pretty much same as your first method...

Func _Choose($vTest, $vVar1, $vVar2, $vVar3="", $vVar4="", $vVar5="", $vVar6="")
    ; $vTest - expression must evaluate to an integer
    ; $var1 - will be returned if $vTest evaluates to 1
    ; $varn - will be returned if $vTest evaluates to n
    ; Returns corresponding value or expression corresponding
    Local $vRet
    Switch $vTest
        Case 1
            $vRet = $vVar1
        Case 2
            $vRet = $vVar2
        Case 3
            $vRet = $vVar3
        Case 4
            $vRet = $vVar4
        Case 5
            $vRet = $vVar5
        Case 6
            $vRet = $vVar6
    EndSwitch
    Return $vRet
EndFunc
Link to comment
Share on other sites

I do it pretty much same as your first method...

 

The main difference between yours and mine is that with yours you would have to remake the function for each case you needed to check for (or add more parameters). For error checking, the first method would be preferred. If you wanted to match a string or variables, my method using delimited strings would be preferred.

Thanks for sharing!

-cb

_ArrayConcatenate2D · Aero Flip 3D · EPOCH (destroy timestamps) · File Properties Modifier · _GetFileType · UpdateEngine<new> · In-line Case (_ICase) <new>

[hr]

50% of the time, it works all the time. -PezoFaSho

Link to comment
Share on other sites

Func _Choose($vTest, $vVar1, $vVar2, $vVar3="", $vVar4="", $vVar5="", $vVar6="")
    ; $vTest - expression must evaluate to an integer
    ; $var1 - will be returned if $vTest evaluates to 1
    ; $varn - will be returned if $vTest evaluates to n
    ; Returns corresponding value or expression corresponding
    Return Eval("vVar" & $vTest)
EndFunc

?

Ever wanted to call functions in another process? ProcessCall UDFConsole stuff: Console UDFC Preprocessor for AutoIt OMG

Link to comment
Share on other sites

That would work for the first method, but it would make the entire script that uses it incompatible with Obfuscator encryption. It also falls back on a specified range of numbers to check, so customization would be a little bit more work.

-cb

_ArrayConcatenate2D · Aero Flip 3D · EPOCH (destroy timestamps) · File Properties Modifier · _GetFileType · UpdateEngine<new> · In-line Case (_ICase) <new>

[hr]

50% of the time, it works all the time. -PezoFaSho

Link to comment
Share on other sites

Interesting idea. I think parameter pairs is a more correct way to do it (though makes the code a little more ugly), the input value is the first parameter, you then pass pairs of cases and results. To have a default value you add it on the end (just a single value without a case value). If theres only pairs then it sets @error if none of the cases are found.

#include <Array.au3>


MsgBox(0, Default, _ICase2("Frap", _
        "Foo", "Bar", _
        "Hello", "World", _
        "Test", "Ing", _
        "Meh", "Be", _
        "Beer", "Yes Please", _
        "N/A") & @CRLF & "@error = " & @error)



Func _ICase2($vValue, _
        $vCase1, $vRet1, _
        $vCase2 = "", $vRet2 = "", _
        $vCase3 = "", $vRet3 = "", _
        $vCase4 = "", $vRet4 = "", _
        $vCase5 = "", $vRet5 = "", _
        $vCase6 = "", $vRet6 = "", _
        $vCase7 = "", $vRet7 = "", _
        $vCase8 = "", $vRet8 = "")
    Local $aCases[8] = [$vCase1, $vCase2, $vCase3, $vCase4, $vCase5, $vCase6, $vCase7, $vCase8]
    Local $aRets[8] = [$vRet1, $vRet2, $vRet3, $vRet4, $vRet5, $vRet6, $vRet7, $vRet8]
    Local $vDefault = Default, $fUseDefault = False

    Local $iPairs

    If Not Mod(@NumParams, 2) Then
        $iPairs = @NumParams / 2 - 1

        $vDefault = $aCases[$iPairs]
        $fUseDefault = True
    Else
        $iPairs = (@NumParams - 1) / 2
    EndIf

    ReDim $aCases[$iPairs]
    ReDim $aRets[$iPairs]

    Local $v
    If $fUseDefault Then
        $v = _ICase2a($vValue, $aCases, $aRets, $vDefault)
    Else
        $v = _ICase2a($vValue, $aCases, $aRets)
    EndIf

    Return SetError(@error, @extended, $v)
EndFunc   ;==>_ICase2

Func _ICase2a($vValue, $aValues, $aReturns, $vDefault = Default)
    If UBound($aValues) <> UBound($aReturns) Then Return SetError(1, 0, "")

    Local $i = _ArraySearch($aValues, $vValue)

    If $i = -1 Then
        If @NumParams < 4 Then
            Return SetError(2, 0, "")
        Else
            Return $vDefault
        EndIf
    EndIf

    Return $aReturns[$i]
EndFunc   ;==>_ICase2a

It's a bit longer but I prefer it to the delimited strings. 

Link to comment
Share on other sites

Nice!

I considered variable pairs, but left them because you lose extensibility. Granted, you likely won't check for more than 20 possible error codes, so a variable method would be the way to go. I like your concept with an unmatched case acting as an else, it's easy and it works great.

Delimited strings were a shot in the dark at an odd concept, but it worked for a very specific application and didn't require much thinking. :mellow: I'll look into updating the code with these other methods for sure. Thanks for sharing.

-cb

_ArrayConcatenate2D · Aero Flip 3D · EPOCH (destroy timestamps) · File Properties Modifier · _GetFileType · UpdateEngine<new> · In-line Case (_ICase) <new>

[hr]

50% of the time, it works all the time. -PezoFaSho

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...