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]].

Tags:

Arrays

Swift