ChunkSequence 🔪🍰

Have cake and eat it

Have a cake and consume the cake by the Swift function, at the same time. Magic.

The nature of the Swift type is that it is copied or copied on write. When I assign A to B (A = B), then effectively B is copy of A.

And there are slices

ArraySlice presents a view onto the storage of some larger array.

A Slice is a view of subrange of the collection. Here is small tip I found useful about that.

I can slice any array in pieces, then process one chunk at a time using the SequenceType. I use it all the time in CryptoSwift, this way I can easily do intermediate computations still working on the same copy of input.

Sequence of pieces

The ChunkSequence struct I demonstrate here (below) is kind of implementation of split() and stride() together. It produces sequence of slices for given Array of elements.

I'll start depiction with the yummy 🎂, then simply use 🔪 to have a 🍰

var 🎂 = ["🍰","🍰","🍰","🍰","🍰"]
for 🍰 in 🎂.slice(every: 2) {
    print(🍰)
}

this results with at most 2 pieces of cake for every person

ArraySlice<🎂> = [🍰,🍰]
ArraySlice<🎂> = [🍰,🍰]
ArraySlice<🎂> = [🍰]

...or boring numbers example:

var array = [1,2,3,4,5]
for slice in array.slice(every: 2) {
    // ArraySlice<Int> = [1,2]
    // ArraySlice<Int> = [3,4]
    // ArraySlice<Int> = [5]
}

slice() is added with convenient Array extension

extension Array {
    func slice(every every: Index) -> ChunkSequence<Element> {
        return ChunkSequence(chunkSize: every, collection: self)
    }
}

built with ChunkSequence struct

struct ChunkSequence<Element>: SequenceType {
    let chunkSize: Array<Element>.Index
    let collection: Array<Element>

    func generate() -> AnyGenerator<ArraySlice<Element>> {
        var offset:Array<Element>.Index = collection.startIndex
        return anyGenerator {
            let result = self.collection[offset..<offset.advancedBy(self.chunkSize, limit: self.collection.endIndex)]
            offset += result.count
            return result.count > 0 ? result : nil
        }
    }
}

a piece of cake. Bon appétit!

Code: gist.github.com/krzyzanowskim/ae4f2c3b35c72a23f220

PS. I wrote more detailed post about Sliceable back in the times of Swift 1.0