Skip to content

Instantly share code, notes, and snippets.

@moaible
Created August 16, 2019 06:53
Show Gist options
  • Save moaible/10602159a3cf700a06c97ef9d837b8c4 to your computer and use it in GitHub Desktop.
Save moaible/10602159a3cf700a06c97ef9d837b8c4 to your computer and use it in GitHub Desktop.
import Foundation
extension Array {
public func chunked(into size: Int) -> [[Element]] {
guard size > 0 else {
fatalError("Chunk size must not be zero")
}
return stride(from: 0, to: count, by: size).map {
Array(self[$0 ..< Swift.min($0 + size, count)])
}
}
public func spliced(at index: Int) -> ([Element], [Element]) {
guard index >= 0 else {
fatalError("Index must no be negative index")
}
guard count + 1 > index else {
fatalError("Index out of range")
}
let lhs = Array(self[0 ..< index])
let rhs = Array(self[index ..< count])
return (lhs, rhs)
}
public func cycleInserted(
at atStart: Int? = nil,
interval: Int,
addElement: (_ insertAt: Int) -> Element) -> [Element] {
if isEmpty {
return self
}
let head: [Element], tail: [[Element]]
if let atStart = atStart {
guard atStart >= 0 else {
fatalError("StartIndex must no be negative index")
}
if count < atStart + interval {
return self
}
let splicedElements: (head: [Element], tail: [Element]) = spliced(at: atStart)
head = splicedElements.head + [addElement(atStart)]
tail = splicedElements.tail.chunked(into: interval)
} else {
if count < interval {
return self
}
head = []
tail = chunked(into: interval)
}
return head + tail.enumerated().map({ (index: Int, elements: [Element]) -> [Element] in
index != tail.count - 1 ?
(elements + [addElement(index)]) : elements
}).flatMap({ $0 })
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment