swiftStacks

Swift doesn't have a dedicated Stack struct. Let's create our own Stack struct.

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

  • push(element): Add an element.
  • pop(): Remove and return an element.
  • peek(): Return the top element of the stack.
  • isEmpty()

First contact

Basically with an array we can do any type of operations, to create a Stack we only have to limit the behavior.

With the code below, you can see that with array methods, we can replicate a Stack functionality. append() to push(), popLast() to 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