Splitting an Array into Sub-Arrays in Swift
// extract unique numbers using a set, then
// map sub-arrays of the original arrays with a filter on each distinct number
let numbers = [1, 1, 1, 3, 3, 4]
let numberGroups = Set(numbers).map{ value in return numbers.filter{$0==value} }
print(numberGroups)
[EDIT] changed to use Set Initializer as suggested by Hamish
[EDIT2] Swift 4 added an initializer to Dictionary that will do this more efficiently:
let numberGroups = Array(Dictionary(grouping:numbers){$0}.values)
For a list of objects to be grouped by one of their properties:
let objectGroups = Array(Dictionary(grouping:objects){$0.property}.values)
If you could use CocoaPods/Carthage/Swift Package Manager/etc. you could use packages like oisdk/SwiftSequence which provides the group()
method:
numbers.lazy.group()
// should return a sequence that generates [1, 1, 1], [3, 3], [4].
or UsrNameu1/TraverSwift which provides groupBy
:
groupBy(SequenceOf(numbers), ==)
If you don't want to add external dependencies, you could always write an algorithm like:
func group<S: SequenceType where S.Generator.Element: Equatable>(seq: S) -> [[S.Generator.Element]] {
var result: [[S.Generator.Element]] = []
var current: [S.Generator.Element] = []
for element in seq {
if current.isEmpty || element == current[0] {
current.append(element)
} else {
result.append(current)
current = [element]
}
}
result.append(current)
return result
}
group(numbers)
// returns [[1, 1, 1], [3, 3], [4]].