Daniel Alvarez

Stacks

swift

A stack uses LIFO (last-in first-out) ordering and these are its basic operations:

First contact

An array can already do everything a stack needs; building a Stack is mostly a matter of restricting that behaviour.

The code below shows how the array methods map onto a stack: append() for push(), popLast() for pop().

var stack: [String] = []

stack.append("A")
stack.append("B")
stack.append("C")

while !stack.isEmpty {
    let e = stack.popLast()
    print(e ?? "")
}

Output

C
B
A

Of course, this alternative is dangerous even for you, if you want a structure that always acts as a Stack you must limit and not leave it open to use other array methods.

Version 1: A struct

struct Stack {
    private var array: [String] = []

    mutating func push(_ element: String) {j
        array.append(element)
    }

    mutating func pop() -> String? {
        array.popLast()
    }

    func peek() -> String? {
        array.last
    }

    var isEmpty: Bool {
        array.isEmpty
    }

    var count: Int {
        array.count
    }
}

Since the push() and pop() functions must modify the content or the array (which is an attribute of the Struct), then it is necessary that this function be mutating. Note that the peek() function does not modify or extract a value, it only reads the top element, that’s why you don’t need the mutating keyword.

Remember that if the function has only one line of code you can save the return keyword.

How to use

var stack = Stack()
stack.push("A")
stack.push("B")
stack.push("C")

while !stack.isEmpty {
    print(stack.pop() ?? "")
}

Version 2: A generic stack

We don’t want a Stack just for Strings, but rather for any type, for that we use Generics.

struct Stack<Element> {
    private var array: [Element] = []

    mutating func push(_ element: Element) {
        array.append(element)
    }

    mutating func pop() -> Element? {
        array.popLast()
    }

    func peek() -> Element? {
        array.last
    }

    var isEmpty: Bool {
        array.isEmpty
    }

    var count: Int {
        array.count
    }
}

How to use

var stack = Stack<String>()

stack.push("A")
stack.push("B")
stack.push("C")

while !stack.isEmpty {
    print(stack.pop() ?? "")
}

You can also see the Queue Struct implementation.

Updated for Swift 5.7