Swift Stack Implementation

Filed Under: Swift

In this tutorial, we’ll be discussing and implementing the Data Structure: Stacks, using Swift. We’ll see how Swift Generics make it easy to create Generic Stacks.

Swift Stack

Stacks are a data structure that is used to hold the data in a particular order.

Let’s see how they are ordered:

The order is like a pile of books. You can keep inserting a new book in the collection at the top.
You can only remove or view the topmost book. That means to remove the bottom-most book, you’ll have to remove all the books above.

This order is known as Last in First Out(LIFO).

Following diagram showcases an example:

swift stack diagram

  • Push is used to insert an element to a stack.
  • Pop is used to remove the topmost element.
  • Peek is used to view the topmost element.

By default, if the Stack is empty, it returns a nil.

We can create Stacks using Arrays, LinkedList etc. We’ll use Arrays for this tutorial.

Important Use case for Stacks

In a music playlist application, where songs are queued and set on shuffle, often you realize that going back and forth changes the next song to a new random song.

This happens through Stacks. The latest song is added on top of a stack. If you don’t like that song, you can always press back (pop) and forward(push) to insert a new random song in the queue.

Let’s launch the XCode playground and implement Swift Stacks.

Create a Stack

We can create a Stack in Swift in the following way:


struct Stack {
  private var myArray: [String] = []
}

We’ve defined a structure Stack that would contain Array of Strings.

Let’s define the functions push, pop and peek in the Swift Structure.

Push


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

This push function appends the new element to the LAST of the array.

Pop


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

This pop function removes the LAST element using the popLast() function available with Swift Arrays.
We’ve used an Optional return type String since it can return a nil.

Peek


func peek() -> String {
        guard let topElement = myArray.last else { print("This stack is empty.") }
        return topElement
    }

If you want to show a custom error message, instead of using Optionals, use the guard let statement of Swift.

This is how our final structure looks in the XCode Playground.


struct Stack {
    private var myArray: [String] = []
    
    mutating func push(_ element: String) {
        myArray.append(element)
    }
    
    mutating func pop() -> String? {
        return myArray.popLast()
    }
    
    func peek() -> String {
        guard let topElement = myArray.last else {return "This stack is empty."}
        return topElement
    }
}

var stack = Stack()
stack.peek()
stack.push("Swift Arrays")
stack.push("Swift LinkedList")
stack.push("Swift Stack")
print(stack)
stack.peek()
stack.pop()
stack.pop()
stack.pop()
stack.peek()
stack.pop()

print stack prints the array

The result of the above Stack operations is:
swift stack string array operations output

The above Stack can only hold Strings. Besides, it doesn’t print the stack contents beautifully.

For that, we can use the CustomStringConvertible protocol as an Extension on our Structure.

Let’s create an extension for the Stack structure below:


extension Stack: CustomStringConvertible {
    var description: String {
        let header = "****Swift Stack Begin****\n"
        let bottomDivider = "\n****Swift Stack End*****\n"
        
        let elements = myArray.joined(separator: "\n")
        
        return header + elements + bottomDivider
    }
}

Following is the output from stack.description

swift stack custom string convertible

It’s printing the stack in the order in which it was pushed. We need to reverse it using the reversed() method:


let elements = myArray.reversed().joined(separator: "\n")

The correct stack order is now:
swift stack custom string convertible correct

Swift Generic Stacks

Let’s make the above Swift stack generic.

You just need to update your Stack definition with a generic parameter in brackets!


struct Stack<T> {
    private var myArray: [T] = []
    
    mutating func push(_ element: T) {
        myArray.append(element)
    }
    
    mutating func pop() -> T? {
        return myArray.popLast()
    }
    
    func peek() -> T? {
        return myArray.last
    }
}

Note: In the CustomStringConvertible protocol, we were joining the elements using joined.
This won’t work for non-string elements. So we need to first map the element to a string using the map operator and then join.


let elements = myArray.reversed().map{ "\($0)" }.joined(separator: "\n")

$0 refers to the current element that’s being mapped.

swift generic stack

We’ve used a Stack of type Any. You can pass anything in place.

This brings an end to this tutorial on Swift Stack implementation.

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages