arraysswiftsubsequencesuffix

How do I get `[Element]` instead of `SubSequence` when dropping/removing elements?


If I remove elements from an array and store it in a variable like this:

let lastFive = myArray.suffix(5)

or this:

let lastFive = myArray.dropLast(5)

lastFive will be Array<SomeType>.SubSequence instead of the element type SomeType. How do I make lastFive become the [Element] rather than a SubSequence?


Solution

  • I like to use this extension:

    extension Sequence {
        func asArray() -> [Element] {
            return Array(self)
        }
    }
    

    That said, both the Collection and Sequence protocols define a sequence() method.

    Sequence.prefix() returns [Element] while Collection.prefix() returns a SubSequence.

    Given an Array defined as follows, we can do some interesting things.

    let myArray = [1, 2, 3, 4, 5]
    

    The following works because the compiler knows to use the Sequence version of suffix().

    func lastFive() -> [Int] {
        return myArray.suffix(5)
    }
    

    Here I'm just using the extension from above.

    func lastFive2() -> [Int] {
        return myArray.suffix(5).asArray()
    }
    

    The following also works because the compiler knows to use the Sequence version of suffix().

    func lastFive3() -> [Int] {
        let suffix: [Int] = myArray.suffix(5)
        return suffix
    }
    

    This does not compile because the compiler assumes you want to use the Collection version of suffix().

    func doesNotCompile() -> [Int] {
        let suffix = myArray.suffix(5)
        return suffix
    }