4
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

Sebastian
  • 7,670
  • 5
  • 38
  • 50
gotnull
  • 26,454
  • 22
  • 137
  • 203
  • 2
    if it works, then it belongs on code review, if it is broken it belongs here – Grady Player Jul 03 '14 at 22:39
  • possible duplicate of [How can I extend typed Arrays in Swift?](http://stackoverflow.com/questions/24027116/how-can-i-extend-typed-arrays-in-swift) – jtbandes Jul 03 '14 at 23:18
  • 3
    Why have you posted this identical question on at least 2 stack exchange sites? – nhgrif Jul 04 '14 at 02:13
  • 1
    There is no need to implement `flatten` at all. `reduce` already _is_ `flatten`. So is `join`, for that matter. – matt Dec 29 '14 at 16:35

1 Answers1

5

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[](), +)
}
Sebastian
  • 7,670
  • 5
  • 38
  • 50