Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Splitting an Array into Sub-Arrays in Swift

Tags:

arrays

swift

Problem

Given an array of values how can I split it into sub-arrays made of elements that are equal?

Example

Given this array

let numbers = [1, 1, 1, 3, 3, 4]

I want this output

[[1,1,1], [3, 3], [4]]

What I am NOT looking for

A possible way of solving this would be creating some sort of index to indicate the occurrences of each element like this.

let indexes = [1:3, 3:2, 4:1]

And finally use the index to rebuild the output array.

let subsequences = indexes.sort { $0.0.0 < $0.1.0 }.reduce([Int]()) { (res, elm) -> [Int] in
    return res + [Int](count: elm.1, repeatedValue: elm.0)
}

However with this solution I am losing the original values. Of course in this case it's not a big problem (an Int value is still and Inteven if recreated) but I would like to apply this solution to more complex data structures like this

struct Starship: Equatable {
    let name: String
    let warpSpeed: Int
}

func ==(left:Starship, right:Starship) -> Bool {
    return left.warpSpeed == right.warpSpeed
}

Final considerations

The function I am looking for would be some kind of reverse of flatten(), infact

let subsequences: [[Int]] = [[1,1,1], [3, 3], [4]]
print(Array(subsequences.flatten())) // [1, 1, 1, 3, 3, 4]

I hope I made myself clear, let me know should you need further details.

like image 621
Luca Angeletti Avatar asked Jul 22 '16 17:07

Luca Angeletti


People also ask

Can you split an array?

Splitting the Array Into Even Chunks Using slice() Method The easiest way to extract a chunk of an array, or rather, to slice it up, is the slice() method: slice(start, end) - Returns a part of the invoked array, between the start and end indices.

How do you split an array into two?

To divide an array into two, we need at least three array variables. We shall take an array with continuous numbers and then shall store the values of it into two different variables based on even and odd values.

How do you split elements in an array?

Example-2: This example uses the splice() method to split the array into chunks of array. This method removes the items from the original array. This method can be used repeatedly to split array of any size. | Split array into chunks.

How do you split in Swift?

To split a string to an array in Swift by a character, use the String. split(separator:) function. However, this requires that the separator is a singular character, not a string.


1 Answers

 // 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)
like image 63
Alain T. Avatar answered Sep 30 '22 03:09

Alain T.