Skip to content

Instantly share code, notes, and snippets.

@pyrtsa
Created October 10, 2014 08:55
Show Gist options
  • Save pyrtsa/dd13d6a750f94788c920 to your computer and use it in GitHub Desktop.
Save pyrtsa/dd13d6a750f94788c920 to your computer and use it in GitHub Desktop.
Decomposing any Sliceable into the first element and the rest in Swift.
/// Split the `Sliceable` collection `coll` into its head and tail.
/// Returns `nil` if the collection is empty.
func decompose<S : Sliceable>(coll: S)
-> (S.Generator.Element, S.SubSlice)?
{
let start: S.Index = coll.startIndex
let end: S.Index = coll.endIndex
return start == end ? nil
: (coll[start], coll[start.successor()..<end])
}
/// Split the `Sliceable` bidirectional collection `coll` into its last
/// element and everything before. Returns `nil` if the collection is empty.
func rdecompose<S : Sliceable where S.Index : BidirectionalIndexType>(coll: S)
-> (S.Generator.Element, S.SubSlice)?
{
let start: S.Index = coll.startIndex
let end: S.Index = coll.endIndex
if start == end {
return nil
} else {
let last = end.predecessor()
return (coll[last], coll[start..<last])
}
}
// MARK: Examples
decompose([1,2,3]) //=> .Some(1, [2,3])
decompose([2,3]) //=> .Some(2, [3])
decompose([3]) //=> .Some(3, [])
decompose(Array<Int>()) //=> nil
decompose("foobar") //=> .Some(("f", "oobar"))
rdecompose("foobar") //=> .Some(("r", "fooba"))
@pyrtsa
Copy link
Author

pyrtsa commented Oct 10, 2014

This is a follow-up to http://www.objc.io/snippets/1.html.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment