Jump to content

Recommended Posts

Posted (edited)

Hello everybody :)
I'm a total newbie to Maps in AutoIt. Instead, I used a few times the similar Scripting.Dictionary object (which is damn fast) . Maybe the advantage of Maps could be that, if one day MS removes the Scripting.Dictionary object (I doubt it but who knows...) then we'll be happy that Maps exist in recent versions of AutoIt.

Anyway, I just started to learn Maps and needed to display at same time the Keys & their corresponding Values. So I scripted this simple reusable function which seems to do the job and is called by one line :

_ArrayDisplay(_Map2D($mMap), "Map Keys & Values")

Mapkeysandvalues.png.5b835f59de18a100664009a29e74bec2.png

Here is the functional example corresponding to the pic :

; AutoIt 3.3.16.1 (Map)

#include <Array.au3>

local $mMap[]
$mMap["Beethoven"] = "Bee"
$mMap["Berlioz"] = "Ber"
$mMap["Chopin"] = Null ; create a key "Chopin" without assigning it a value

_ArrayDisplay(_Map2D($mMap), "Map Keys & Values")

Func _Map2D(Const ByRef $mMap)
    Local $aMapKeys = MapKeys($mMap)
    Local $aMap2D[Ubound($aMapKeys)][2]

    Local $iRow = - 1
    For $vKey In $aMapKeys ; or a simple For... loop as commented out below
        $iRow += 1 ; 0+
        $aMap2D[$iRow][0] = $vKey
        $aMap2D[$iRow][1] = $mMap[$vKey]
    Next

;~  For $i = 0 To Ubound($aMapKeys) - 1
;~      $aMap2D[$i][0] = $aMapKeys[$i]
;~      $aMap2D[$i][1] = $mMap[$aMapKeys[$i]]
;~  Next

    Return $aMap2D
EndFunc

I just tested it on 10.000 pairs of key/values created by using the code below and the return from the function was immediate :

For $i = 0 To 9999
    $mMap[$i] = $i + 10
Next

If you guys got some improvements for the function, please share them here, thanks.

 

Edited by pixelsearch
typo

"I think you are searching a bug where there is no bug... don't listen to bad advice."

  • 1 year later...
Posted (edited)

I have made some helpful functions for maps based on yours, which I use regularly
and I wanted to share them

Thank you very much :)

#include <Array.au3>
#include <String.au3>

Local $mMap[], $mMapOfMap[]
$mMap["Beethoven"] = "Bee"
$mMap["Berlioz"] = "Ber"
$mMap["Chopin"] = Null ; create a key "Chopin" without assigning it a value

Local $aArray = [$mMap.Beethoven, $mMap.Berlioz, $mMap.Chopin]
$mMap["Array"] = $aArray

$mMapOfMap.Map1 = $mMap

ConsoleWrite("$mMap.Array[1]=" & $mMap.Array[1] & @CRLF)

_MapCW($mMap)

_MapClear($mMap)

_MapCW($mMap)

_MapCW($mMapOfMap)

_MapCW($mMapOfMap.Map1)

ConsoleWrite("" & @CRLF)
ConsoleWrite("$mMapOfMap.Map1.Array[1]=" & $mMapOfMap.Map1.Array[1] & @CRLF)
ConsoleWrite("$mMapOfMap.Map1.Berlioz=" & $mMapOfMap.Map1.Berlioz & @CRLF)


Func _Map2D(ByRef $mMap)
    Local $aMapKeys = MapKeys($mMap)
    Local $aMap2D[UBound($aMapKeys)][2]
    For $i = 0 To UBound($aMapKeys) - 1
        $aMap2D[$i][0] = $aMapKeys[$i]
        $aMap2D[$i][1] = $mMap[$aMapKeys[$i]]
    Next
    Return $aMap2D
EndFunc   ;==>_Map2D

Func _MapCW(ByRef $m, $sTitle = "--- Map info ---")
    ConsoleWrite($sTitle & @CRLF)
    Local $aObject = _Map2D($m)
    Local $iMaxKeyLen = 0
    Local $sKey
    For $i = 0 To UBound($aObject) - 1
        $sKey = $aObject[$i][0]
        If StringLen($sKey) > $iMaxKeyLen Then
            $iMaxKeyLen = StringLen($sKey)
        EndIf
    Next

    For $i = 0 To UBound($aObject) - 1
        $sKey = $aObject[$i][0]
        Local $vValue = $aObject[$i][1]
        Local $sPadding = _StringRepeat(" ", $iMaxKeyLen - StringLen($sKey) + 1)
        Local $sDim, $sLabel = ""
        Local $iDimension

        If IsMap($vValue) Then
            $sLabel = "= {Map[" & UBound($vValue) & "]}"
            ConsoleWrite($sKey & $sPadding & $sLabel & @CRLF)
        ElseIf IsArray($vValue) Then
            $iDimension = UBound($vValue, $UBOUND_DIMENSIONS) ; The dimension of the array e.g. 1/2/3 dimensional.
            $sDim = ""
            For $d = 1 To $iDimension
                $sDim &= "[" & UBound($vValue, $d) & "]"
            Next
            $sLabel = "= {Array" & $sDim & "}"

            ConsoleWrite($sKey & $sPadding & $sLabel & @CRLF)
        Else
            ConsoleWrite($sKey & $sPadding & "= " & $vValue & @CRLF)
        EndIf
    Next
EndFunc   ;==>_MapCW

Func _MapClear(ByRef $mMap)
    Local $m[]
    $mMap = $m
EndFunc   ;==>_MapClear

 

Edited by ioa747

I know that I know nothing

  • 4 months later...
Posted (edited)

Hello everybody :)
Just upgraded _Map2D() to _Map2DEx()

_Map2DEx() takes care of a nested Map or a nested 1D array or a simple value.
The goal is still the same, i.e. a final display using _ArrayDisplay()

For now, it requires that the nested map or nested array got the same number of keys (when map) or elements (when 1D array)
Here is the function _Map2DEx() with examples :

#include <Array.au3>

Opt("MustDeclareVars", 1)

_MapInMap()
_ArrayInMap()
_SimpleValueInMap()

;==============================================
Func _MapInMap()

    Local $mMap[], $mPerson[]

    $mPerson["first"] = "Jerry"
    $mPerson["name"] = "Mouse"
    $mMap["42"] =  $mPerson

    $mPerson["first"] = "Tom"
    $mPerson["name"]  = "Cat"
    $mMap["43"] = $mPerson

    $mPerson["first"] = "Bucks"
    $mPerson["name"] = "Bunny"
    $mMap["44"] = $mPerson

     _ArrayDisplay(_Map2DEx($mMap), "Map in Map", Default, Default, Default, "ID | first | name")
EndFunc   ;==>_MapInMap

;==============================================
Func _ArrayInMap()

    Local $mMap[], $aPerson[2]

    $aPerson[0] = "Jerry_2"
    $aPerson[1] = "Mouse_2"
    $mMap["42"] =  $aPerson

    $aPerson[0] = "Tom_2"
    $aPerson[1]  = "Cat_2"
    $mMap["43"] = $aPerson

    $aPerson[0] = "Bucks_2"
    $aPerson[1] = "Bunny_2"
    $mMap["44"] = $aPerson

    _ArrayDisplay(_Map2DEx($mMap), "Array in Map", Default, Default, Default, "ID | first | name")
EndFunc   ;==>_ArrayInMap

;==============================================
Func _SimpleValueInMap()

    Local $mMap[]

    $mMap["Beethoven"] = "Bee"
    $mMap["Berlioz"] = "Ber"
    $mMap["Chopin"] = Null ; create a key "Chopin" without assigning it a value

    _ArrayDisplay(_Map2DEx($mMap), "Simple value in Map", Default, Default, Default, "Key  | Value")
EndFunc   ;==>_SimpleValueInMap

;==============================================
Func _Map2DEx(Const ByRef $mMap)

    Local $aMapKeys = MapKeys($mMap), $iRows = Ubound($aMapKeys)

    If $iRows = 0 Then
        Local $aMap2D[0][0]
        Return $aMap2D
    EndIf

    Local $sType = VarGetType($mMap[$aMapKeys[0]]), $iCols = UBound($mMap[$aMapKeys[0]]), $iRow = -1
    Local $aMap2D[$iRows][ $iCols + (($sType = "Map" Or $sType = "Array") ? 1 : 2) ]

    Select
        Case $sType = "Map"
            Local $iCol
            For $vKey In $aMapKeys
                $iRow += 1
                $aMap2D[$iRow][0] = $vKey
                $iCol = 0
                For $vKey2 In MapKeys($mMap[$vKey])
                    $iCol +=1
                    $aMap2D[$iRow][$iCol] = $mMap[$vKey][$vKey2]
                Next
            Next

        Case $sType = "Array"
            For $vKey In $aMapKeys
                $iRow += 1
                $aMap2D[$iRow][0] = $vKey
                For $j = 1 To $iCols
                    $aMap2D[$iRow][$j] = ($mMap[$vKey])[$j - 1] ; mandatory syntax ( $mMap[] ) []
                Next
            Next

        Case Else ; simple value
            For $vKey In $aMapKeys
                $iRow += 1
                $aMap2D[$iRow][0] = $vKey
                $aMap2D[$iRow][1] = $mMap[$vKey]
            Next
    EndSelect

    Return $aMap2D
EndFunc   ;==>_Map2DEx

_Map2DEx.png.8141287666a8bbdb4cdb818d2f1eb554.png

Have a great day :bye:

Update August 23, 2026 (same day)
Minor change : instead of declaring $aMap2D three times inside Select...EndSelect, declare it only once outside Select...EndSelect

Edited by pixelsearch
Update August 23, 2026 (same day)

"I think you are searching a bug where there is no bug... don't listen to bad advice."

Posted
4 hours ago, argumentum said:

use only strings as key because [...]

Hey argumentum :)
Isn't it what I did throughout the whole script ?

"I think you are searching a bug where there is no bug... don't listen to bad advice."

  • Moderators
Posted (edited)

I'm curious about Maps() (I stopped right after they were integrated).

Since Int is a knowin issue, would it be better using SQLite to map?

<Map idiot here.. This kind of thing erks me as a production model that has issues, thus my question(s)>

Almost better to String()/Hex() the values and create a sub category that show type of var so you can unravel, but then why stray from an array or SQLite db if that's the case...

I'm not trolling, I am truly asking what benefit something that is explicitly broke plays?

Thanks

Edit:

Would almost be better to set it up like DllStuctCreate(); eg. str;data, int;data and have the backend interpreter fix the search feature... but if I'm being honest, It's much safer and better to use SQLite mapping, I did this once and I never ran into an issue using any "type".  You just use a memory db.  But if I were to use this internal feature, I'd prefer to type strict it like DllStructCreate().  This just my personal opinion.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

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
×
×
  • Create New...