Last active
June 14, 2018 07:51
-
-
Save jnd-au/1f6e61dd8f2f9e986223 to your computer and use it in GitHub Desktop.
Swift: Group array values into a dictionary by key mapping (Curryable version)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Given an array collection (may be a Swift Array or an Objective-C NSArray) | |
// and a function that optionally maps each element to its corresponding group, | |
// return a Swift Dictionary of the mapped elements in their groups. | |
// | |
// Usage: | |
// func keyFunc(o: V) -> K {...} | |
// let grouped = groupBy(keyFunc)([V]) | |
// | |
// Example: | |
// func length(s: String) -> Int { return countElements(s) } | |
// let grouped = groupBy(length)(["A", "BB", "AB", [], NSDate()]) // [2: ["BB", "AB"], 1: ["A"]] | |
func groupBy<K,V>(keyFunc: V -> K?) -> ([AnyObject]) -> [K: [V]] { | |
var grouped = [K: [V]]() | |
func group(collection: [AnyObject]) -> [K: [V]] { | |
for c in collection { | |
if let o = c as? V { | |
if let k = keyFunc(o) { | |
if var group = grouped[k] { | |
group.append(o) | |
grouped[k] = group | |
} | |
else { | |
grouped[k] = [o] | |
} | |
} | |
} | |
} | |
return grouped | |
} | |
return group | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Rather than only working on arrays, it looks like it could be generalized to handle arbitrary sequence types. Perhaps a SequenceType where SequenceType.GeneratorType.Element == AnyObject
Perhaps no type constraint needed.
Any time I see for-in used in a generic finction with arrays only, I want to replace the array with the most general generic type the for-in can handle.
Any idea if a groupby method is the works to be standardized in Swift 3? It belongs with map, filter and reduce as a standard aggregate method.