Limited Stack

(Xcode 8.0, OSX 10.11)

For the app I am currently working on, I wanted to implement the following:

– user can import a picture
– user can change their mind and undo their choice, up to a point
– I don’t need to store a million images in my app

And there are many ways of implementing this, but the simplest seemed to be a limited stack, so I’ve put that CS knowledge to good use (Ahem. I don’t have a CS degree. But I’ve read a book. That totally counts.) and implemented a custom collection: you can set how many items you want to use, and you get to set a default item, so that calls to ‘pop’ always return a valid object.

This stack is backed by an array, and it’s not optimised for anything; this is a sheer convenience class.

struct LimitedStack <T> {

I like generics. I don’t always like the syntax, but once you remember that you need to declare T in advance, they’re nice and easy to use.

var limit: Int

var stack: Array<T>= [] var defaultElement: T

You can, of course, create a LimitedStack that mimicks the functionality of Array etc – if there is no first element, you can’t have one – but at some point, you need to think about the default value you want to return. I find that integrating it into the stack makes me think about appropriate defaults.

init (limit: Int, defaultElement: T){
self.limit = limit
self.defaultElement = defaultElement
}

This is the basic initialiser. It would be useful to initialise a LimitedStack from an Array and from another LimitedStack, but right now, we’ll use only the basic case.

mutating func pop () -> T {
guard stack.count > 0 else {
return defaultElement
}
let result = stack.removeLast()
return result
}

mutating func push(element: T) -> () {
let safeZone = limit - 1
if stack.count <= safeZone {
stack.append(element)
} else {
stack.remove(at: 0)
stack.append(element)
}
}

The push and pop functions. If there’s no element to be popped, I return the default; if the number of elements in the stack is less than the default, I tag the new element on at the end, otherwise, I drop the first and then add the new element.