Skip to content

Instantly share code, notes, and snippets.

@ole
Last active November 7, 2018 14:18
Show Gist options
  • Save ole/1e3f1b3d2f8ca1f5b79de262f74678d0 to your computer and use it in GitHub Desktop.
Save ole/1e3f1b3d2f8ca1f5b79de262f74678d0 to your computer and use it in GitHub Desktop.
Swift challenge: Sequence.headAndTail. Context: https://twitter.com/olebegemann/status/1059923129345196032
// Challenge: Fill out this extension
//
// I have a solution for this return type:
//
// var headAndTail: (head: Element, tail: AnySequence<Element>)?
//
// I don't think it can be done with tail: SubSequence.
extension Sequence {
/// Destructures `self` into the first element (head) and the rest (tail).
/// Returns `nil` if the sequence is empty.
var headAndTail: (head: Element, tail: SubSequence)? {
// ,,,
}
}
// Test case 1:
assert([1, 2, 3].headAndTail! == (1, [2, 3]))
// Test case 2 (a consuming sequence):
var i = 1
let seq = AnySequence {
AnyIterator { () -> Int? in
defer { i += 1 }
return i
}
}
let (head, tail) = seq.headAndTail!
assert(head == 1)
assert(Array(tail.prefix(3)) == [2,3,4])
// Printing the output for debugging
// Note that because the sequence is self-consuming, just commenting out the last line
// will always print something else than 2 3 4. You must also comment the related
// assertion above.
print(head) // should output 1
//tail.prefix(3).forEach { print($0) } // should output 2 3 4
@ole
Copy link
Author

ole commented Nov 7, 2018

Update: @dennisvennink found a solution using drop(while:) to "catch" the first element before it gets lost: https://gist.github.com/dennisvennink/e8b1921916d3c2f90ab52f47291145ef

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