I found this article (First and Rest) by chance. In this article, he explains the best way to take an array and split it into its first and remaining elements. I think it is interesting, so I tried my hand at it. I recommend you to read his article before you read my article.

When I saw the following way,

``````// From his article
func loop(_ c: [Int]) {
let (first, rest) = (c.first, c.dropFirst())
guard let someFirst = first else {
return
}

print(someFirst)
loop(Array(rest))
}

loop([1,2,3,4]) // => 1,2,3,4
``````

I prefer to this way in my opinion because `rest` variable looks a little bit verbose for me.

``````// Just remove `rest` variable
func loop(_ c: [Int]) {
guard let first = c.first else {
return
}

print(first)
loop(Array(c.dropFirst))
}

loop([1,2,3,4]) // => 1,2,3,4
``````

In the last way in his blog, I really see it as a beautiful way.

``````// From his article
func loop(_ c: [Int]) {
guard case
let(first?, rest) = (c.first, c.dropFirst())
else {
return
}

print(first)
loop(Array(rest))
}

loop([1,2,3,4]) // => 1,2,3,4
``````

Only one thing I have concern is that `Array(rest)`. As he mentions,

Well, almost. Note that dropFirst() returns an ArraySlice. Because loop expects an Array, we have to convert rest before passing it to loop(). Reworking loop() to take a generic Collection would get around this — at the expense of being less blog-friendly

The problem is returns type was `ArraySlice`. To be exact, It will be `ArraySlice<Int>` in this case. It’s like a collection wrapper. The most easiest way to solve it is like this.

``````func loop(_ c: ArraySlice<Int>) {
guard let first = c.first else {
return
}

print(first)
loop(c.dropFirst())
}

loop([1,2,3,4]) // => 1,2,3,4
``````

If you want more generic way,

``````func loop<T>(_ c: ArraySlice<T>) {
guard let first = c.first else {
return
}

print(first)
loop(c.dropFirst())
}

loop([1,2,3,4]) // => 1,2,3,4
loop(["hoge","fuga","foo"]) // => "hoge","fuga","foo"
``````

Instead of `ArraySlice<T>`, it may be good to use `AnyCollection<T>`. It means I use Type erasure. I don’t need to care about what type it is.

``````func loop<T>(_ c: AnyCollection<T>) {
guard let first = c.first else {
return
}

print(first)
loop(c.dropFirst())
}

loop(AnyCollection([1,2,3,4])) // => 1,2,3,4
loop(AnyCollection(["hoge","fuga","foo"])) // => "hoge","fuga","foo"
``````

In this case, I’ll use `Collection protocol` becuase they have an instance property `var first: Self.Iterator.Element?` and a method of `func dropFirst(Int)` as an instance method. But it has error for now…

``````// Not working!!
func loop<C: Collection>(_ c: C) {
guard let first = c.first else {
return
}

print(first)
loop(c.dropFirst()) // Error!! Argument type 'S.SubSequence' does not conform to expected type 'Sequence'
}
``````

### Conclusion

I think I need to try other ways to find a best way. But for me, I like Type erasure way because it’s very simple and generic. Do you have an any thought? Please share your opinion and idea.

Ref.