Skip to content

Commit

Permalink
Add stdEnumerator::CreateFromDictionaryEx and `stdEnumerator#groupB…
Browse files Browse the repository at this point in the history
…yEx`
  • Loading branch information
sancarn committed Jul 8, 2024
1 parent 682871e commit c818a62
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 5 deletions.
4 changes: 3 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,6 @@ Before `08/07/2021` a change log was not kept. We have retrospectively gone back
- 2024-07-01 `stdAcc` FIX - Fixed bug where numerous states weren't being correctly identified.
- 2024-07-04 `stdWindow` FEATURE - Added `stdWindow::Create()`, allowing users to create windows, and `stdWindow::CreateHighlightRect()` to create a window with a highlight rectangle. Also added `stdWindow#hDCClient` to get the hDC of the client area of the window.
- 2024-07-04 `stdWindow` FIX - Fixedd bug where `stdWindow#Visible` would focus the window it changed visibility of. This has been fixed.
- 2024-07-04 `stdJSON` FIX - Fixed bug where `stdJSON` wasn't correctly handling strings with `"` in them.
- 2024-07-04 `stdJSON` FIX - Fixed bug where `stdJSON` wasn't correctly handling strings with `"` in them.
- 2024-07-08 `stdEnumerator` FEATURE - `stdEnumerator::CreateFromDictionaryEx` added. Translates a dictionary to a Enumerator of dictionaries with key and value properties. Additionally added `stdEnumerator#groupByEx` which utilises the above.
- 2024-07-08 `stdLambda` FIX - Removed `key` from the dictionary checks in `stdLambda#stdCallByName`. Shouldn't be a breaking change, because `key` isn't a method on type `Dictionary`.
46 changes: 43 additions & 3 deletions src/stdEnumerator.cls
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,32 @@ End Function
'@param iMaxLength - Maximum length of enumerator. The enumerator will refuse to go beyond this number of items. Used in order to prevent runaway processes.
'@returns - An enumerator representing the dictionary data
'@TODO: Finish function - requires key handling. Might be a bit of a pain as it requires refactoring to work with collection keys among other things.
Private Function CreateFromDictionary(ByVal o as object, optional byval iMaxLength as long = 1000000) as stdEnumerator
set CreateFromDictionary = new stdEnumerator
'Call CreateFromDictionary.protInit(EnumeratorType.FromDictionary,iMaxLength,o)
'may not be needed given we have `CreateFromDictionaryEx`, but it would be far more performant.
Private Function CreateFromDictionary(ByVal dictionary as object, optional byval iMaxLength as long = 1000000) as stdEnumerator

End Function

'Translates a dictionary to a Enumerator of dictionaries with key and value properties.
'@constructor
'@param dictionary - The dictionary to create the enumerator from.
'@param iMaxLength - Maximum length of enumerator. The enumerator will refuse to go beyond this number of items. Used in order to prevent runaway processes.
'@returns stdEnumerator<Object<Scripting.Dictionary<key: string, value: variant>>> - An enumerator representing the dictionary data
'@example ```
'set dict = stdEnumerator.CreateFromArray(Array(1,2,3,2,2,1,3,2,3,1,2,3)).groupBy(stdLambda.Create("$1"))
'set dictEx = stdEnumerator.CreateFromDictionaryEx(dict).forEach(stdLambda.Create("let $1.value = $1.value.count")).sort(stdLambda.Create("$1.count")).last
'```
Public Function CreateFromDictionaryEx(ByVal dictionary as object) as stdEnumerator
Dim keys as variant: keys = dictionary.keys()
Dim items as variant: items = dictionary.items()
Dim rows as collection: set rows = new collection
For i = 0 to ubound(keys)
Dim row as object: set row = CreateObject("Scripting.Dictionary")
row.CompareMode = vbTextCompare
row.add "key", keys(i)
row.add "value", items(i)
rows.add row
next
set CreateFromDictionaryEx = stdEnumerator.CreateFromIEnumVariant(rows)
End Function

'Initialse the stdEnumerator
Expand Down Expand Up @@ -955,6 +978,23 @@ Public Function groupBy(ByVal cb as stdICallable) as object
set groupBy = oRet
End Function

'Returns a new enumerator containing groups from groupBy, with the key and item properties added
'@param cb as stdICallable<(element: Variant)=>Variant> - The callable which when run on an element returns the key to group by
'@returns stdEnumerator<Object<Dictionary<key:string, item:variant>>> - Enumerator containing grouped data
'@example ```
'Dim e as stdEnumerator: set e = stdEnumerator.CreateFromArray(Array(1,2,3,2,2,1,3,2,3,1,2,3))
'Debug.Print e.groupByEx(stdLambda.Create("$1")).Map(stdLambda.Create("$1.key & ""-"" & $1.value.length")).Join(";")
'```
'@example ```
''Get the largest count
'Dim e as stdEnumerator: set e = stdEnumerator.CreateFromArray(Array(1,2,3,2,2,1,3,2,3,1,2,3))
'Debug.Print e.groupByEx(stdLambda.Create("$1")).Sort(stdLambda.Create("-1 * $1.value.length")).Item(1)("key")
'```
Public Function groupByEx(ByVal cb as stdICallable) as stdEnumerator
Dim groups as object: set groups = groupBy(cb)
set groupByEx = CreateFromDictionaryEx(groups)
End Function

'Obtains the maximum value from the enumerator. If a callback is given the item which returns the largest value from the callback is returned.
'@param cb as stdICallable<(element: Variant)=>Variant> - If callback given, callback to obtain max value of. Else max of the elements values are found.
'@returns - Value containing max data
Expand Down
2 changes: 1 addition & 1 deletion src/stdLambda.cls
Original file line number Diff line number Diff line change
Expand Up @@ -1344,7 +1344,7 @@ Private Function stdCallByName(ByRef obj As Object, ByVal funcName As String, By
'If Dictionary and
If TypeName(obj) = "Dictionary" Then
Select Case funcName
Case "add", "exists", "items", "keys", "remove", "removeall", "comparemode", "count", "item", "key"
Case "add", "exists", "items", "keys", "remove", "removeall", "comparemode", "count", "item"
'These methods already exist on dictionary, do not override
Case Else
Select Case callerType
Expand Down

0 comments on commit c818a62

Please sign in to comment.