Jump to content

Recommended Posts

  • Moderators
Posted (edited)

This was a place holder post to spark interest - much better implementations than my initial thoughts found later in the thread. :)

M23

Edited by Melba23
Removed code

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:

  Reveal hidden contents

 

  • Moderators
Posted

Zedna,

Sorry - typo. :>

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:

  Reveal hidden contents

 

Posted

A couple of points for the examples.

  • Global should be changed to Local.
  • Variables undeclared and fail Au3Check with additional settings.
  • They should be encased in an example function as well. Similar to the Map* functions.
  • Run Tidy on both the examples and includes.
  • Remove EOLs at the end of the Map.au3 and just leave a single CRLF.

 

PS I can make these changes myself once committed.

With _MapToString() I feel there should be consistency between that function and _ArrayToString(). For example I would expect it to print {Array} as it does in _MapToString(). I am guessing people will start to expect _ArrayToString() to have the same output when an array or map is used.

#include <MsgBoxConstants.au3>
#include <Map.au3>

Local $mMap[], $aTemp = [0, 1, 2, 3, 4, 5]
$mMap.Tom = "Tom value"
$mMap.Dick = $aTemp
$mMap.Harry = "Harry value"

Local $sMap = _MapToString($mMap)
MsgBox($MB_SYSTEMMODAL, "Map string", $sMap)
ClipPut($sMap)

Local $aArray = ["Tom value", $aTemp, "Harry value"]
Local $sArray = _ArrayToString($aArray) ; Tom value|{Array}|Harry value
MsgBox($MB_SYSTEMMODAL, "Array string", $sArray)

In _MapToArray() I feel the addition of quotes should be left to the user as this function should be a straight map to array function only. If the user wants quotes then it's up to them to add this cosmetic feature.

Great work by the way. It's just I have managed to sit down today and go through the proposed UDF in full.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted

Small remark

I don't know where the Map name come from.

Anyway I suggest the naming of such variable start with "m" as opposed to "a" for Array

  • Moderators
Posted

guinness,

Thanks for the encouraging words. I will look at changing the Array functions to return the same sort of {---} content as the Map ones when dealing with internal arrays/maps. :)

jpm,

  Quote

I don't know where the Map name come from

Jon decided >here (private forum) - and the $m prefix comes from there too. :)

And there are lots of $aMap array variables in the UDF as the $mMap maps are converted for manipulation/iteration/etc. ;)

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:

  Reveal hidden contents

 

Posted

  On 7/28/2014 at 10:48 AM, Melba23 said:

guinness,

Thanks for the encouraging words. I will look at changing the Array functions to return the same sort of {---} content as the Map ones when dealing with internal arrays/maps. :)

jpm,

Jon decided >here (private forum) - and the $m prefix comes from there too. :)

And there are lots of $aMap array variables in the UDF as the $mMap maps are converted for manipulation/iteration/etc. ;)

M23

Thanks for pointing the post

$m must be added to Wiki

Posted (edited)

I understand the appeal of converting the map into an array and then reusing existing array functions to do the hard work. For _MapDisplay this makes a lot of sense, considering how much heavy lifting Array.au3 does. However, considering maps may hold millions of items converting the entire structure into an array can take several seconds*. Functions _MapMaxKey, _MapMinKey, _MapMaxValue, _MapMinValue, _MapFindAll, _MapSearch and _MapToString probably should not be calling _MapToArray.

* Preliminary speedtest with latest beta. 100K elements converted into array: 63 seconds. (Might be a problem with map implementation though)

Edit #100: Couldn't sleep. Code may not be the best.

I changed the map iteration stuff to For $vKey In MapKeys($mMap) everywhere. It looks better and sets a good example.

Changelog:

 - _MapFindAll: Removed _MapToArray on the input

 - _MapFindAll: Do not declare empty array as the maximum-size of the input (e.g. $avResult[uBound($aMap)] ) but use a sexy new map to solve that $avResult[] (we have lists now, everyone!). Kind of a shame I had to Return _MapToArray($avResult) at the end.

 - _MapMaxKey: Removed _MapToArray on the input

 - _MapMinKey: Removed _MapToArray on the input

 - _MapSearch: Removed _MapToArray on the input

 - _MapToArray: Code cleanup.

 - _MapToString: Code cleanup. 

Here is a diff: http://www.mergely.com/J2OQdvns/ (P.S. We need better tools.)

Map.au3

Edited by Manadar
Posted

Perhaps a common function set should be created between Array.au3 and Map.au3? To reduce duplicate code. Personally I prefer tidy and easy to maintain code first, then consider the speed factor afterwards.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted (edited)

  On 7/28/2014 at 8:12 PM, guinness said:

Perhaps a common function set should be created between Array.au3 and Map.au3? To reduce duplicate code. Personally I prefer tidy and easy to maintain code first, then consider the speed factor afterwards.

Forgotten this from my last post.

 

I broke _MapFindAll and _MapSearch. And maybe the _MapMin / _MapMax as well. The code for comparisons need to be shared between Array and Map in a different way than converting to arrays and calling array libraries.

 

MapSearch documentation has reference to $iCase?

 

_MapSearch ( Const ByRef $mMap, $vValue [, $iCompare = 0 ] )


###Parameters###
@@ParamTable@@
$mMap
    The Map to search
$vValue
    The specified value for which to search
$iCompare
    [optional]
        0 Casting of variables to the same type (default), "string" = 0, "" = 0 or "0" = 0 match (If $iCase = 0)

Edit: And it also would be really awesome if _ArrayDisplay took a map and just displayed it no questions asked. Check _MapFindAll for why. I'm expecting to see this pattern way more often in the future. Basically it's the "If you make a map with just integers keys, you have a list" realization.

Edited by Manadar
Posted (edited)
  On 7/28/2014 at 9:57 PM, Zedna said:

@Manadar

I think _MapSearch() should return something (null?) or SetError when nothing is found.

http://www.mergely.com/J2OQdvns/

 

I think it should be like this

Func _MapSearch(Const ByRef $mMap, $vSearch, $iCompare = 0)

    If Not IsMap($mMap) Then Return SetError(1, 0, -1)
    If $iCompare = Default Then $iCompare = 0

    For $vKey In MapKeys($mMap)
        $vValue = $mMap[$vKey]

        If $vValue == $vSearch Then
            Local $aResult[]
            $aResult[$vKey] = $vValue
            Return $aResult
        EndIf
    Next

    Return Null

EndFunc   ;==>_MapSearch

You either get null if nothing is found, or you get the whole key/value pair in a map. Not finding what you were looking for in a map is not really an error condition so no @error here.

Edited by Manadar
Posted
  On 7/29/2014 at 7:08 AM, Manadar said:

I think it should be like this

Not finding what you were looking for in a map is not really an error condition so no @error here.

Couldn't agree more.

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted

Manadar,

In  _MapToString() you are checking if a key is a map or an array, though they can only be integers or strings. Also the function wasn't returning anything as you were only updating the $sOutput variable if it was a map or an array.

Also _MapSearch() isn't using the $iCompare variable.

Local $mMap[]
For $i = 0 To 19
    $mMap[$i] = $i
Next
ConsoleWrite(_MapToString($mMap) & @CRLF)

Func _MapToString(Const ByRef $mMap, $sDelim_Item = "|", $sDelim_Row = @CRLF)
    If $sDelim_Item = Default Then $sDelim_Item = "|"
    If $sDelim_Row = Default Then $sDelim_Row = @CRLF
    If Not IsMap($mMap) Then Return SetError(1, 0, -1)

    Local $sRet = "", _
            $vValue = 0

    For $vKey In MapKeys($mMap)
        $vValue = $mMap[$vKey]
        $sRet &= $vKey & $sDelim_Item
        __MapToString_Print($sRet, $vValue)
        $sRet &= $sDelim_Row
    Next

    $sRet = StringTrimRight($sRet, StringLen($sDelim_Row)) ; Strip the last delimiter.
    Return $sRet
EndFunc   ;==>_MapToString

Func __MapToString_Print(ByRef $sOutput, ByRef $vValue)
    Switch VarGetType($vValue)
        Case "Array"
            $sOutput &= "{Array}"
        Case "Map"
            $sOutput &= "{Map}"
        Case Else
            $sOutput &= $vValue
    EndSwitch
EndFunc   ;==>__MapToString_Print

UDF List:

  Reveal hidden contents

Updated: 22/04/2018

Posted (edited)

Thanks guinness, czardas. Was just working on it and included your feedback.

 

Changelog:

- New: _MapKeysToArray

- New: _MapValuesToArray

- Fixed: _MapToString / _MapToClip not working

- Changed: Added $iCase to _MapSearch and _MapFindAll

- Changed: Split comparison logic into new function __MapSearchComparison. (needs testing) I did not update Array.au3 because _ArraySearch code is a mess. : (

- Changed: _ArrayDisplay will call _MapDisplay when it receives a map

- Changed: _MapSearch returns a key/value pair or null

- Removed: _MapToArray $bString parameter to quote keys (and put this in _MapDisplay since it is highly specific for the purpose of displaying a map)

 

Diff: http://mergely.com/hUuFirz8/

 

 

 

I'm not sure if we should include _MapRenameKey. Worst case scenario it will end up making two whole array copies. That may surprise someone who uses the library therefore it's a leaky abstraction.

 

Apart from maybe Array.au3 rewrites I don't expect much more changes to Map.au3

Map UDF and Examples.zip

Edited by Manadar
Posted

Hi,

I don't like to have _ArrayDisplay() to call _MapDisplay() as other Array functions will need to retrieve an extra include for nothing.

_ArrayDisplay should display array. Perhaps _MapDisplay() can display one or the other as the syntax are very similar.

If we want not to include all Array.au3 in Map.au3 we can isolate _ArrayDisplay() in a new include

Cheers

Jpm

Posted

  On 7/29/2014 at 2:35 PM, TypeIt said:

Should that contain other functions can operate on both types?

Not every include file needs to be public.

Where possible, yes, in most cases it won't save us anything though. _ArrayDisplay is a special case in that the code is very long, so the actual array processing is a relatively small part of it.

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
  • Recently Browsing   0 members

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