gotnull
gotnull

Reputation: 27224

How to implement flatten as an extension on an Array without type casting?

extension Array {
  func flatten<T>() -> T[] {
    let xs = (self as Any) as Array<Array<T>>
    return xs.reduce(T[](), +)
  }
}

It works, but I'm not sure if all those casts are required.

Is there a better way?

For comparison, here is the implementation in one of the swift extension libraries. I'm not sure if they have it all figured out too -- their implementation begins with the following comment:

// There's still some work to do here

Upvotes: 4

Views: 997

Answers (1)

Sebastian
Sebastian

Reputation: 7720

You can't extend a specific type of a generic type in Swift:

extension Array<Int> {
}

error: non-nominal type 'Array' cannot be extended

But you can write a function that takes a specific type of array. If you want to flatten an array of arrays (Array<T[]>, T[][] or Array>) your functions signature would look like this:

func flatten<T> (array: Array<T[]>) -> T[]

It takes an array of arrays of T and returns an array of T. You can then use your approach with reduce:

func flatten<T> (array: Array<T[]>) -> T[] {
    return array.reduce(T[](), +)
}

Upvotes: 5

Related Questions