Skip to content

Instantly share code, notes, and snippets.

@jnd-au
Last active June 14, 2018 07:51
Show Gist options
  • Save jnd-au/1f6e61dd8f2f9e986223 to your computer and use it in GitHub Desktop.
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)
// 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
}
@paulbuis
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment