DSA: Stacks in Swift

Abdullah Bilgin
Swift Insights
Published in
4 min readNov 28, 2023

Data Structures & Algorithms: Books on a Shelf: Unveiling the Magic of Stacks in Swift 📚

In the enchanting world of programming, concepts like stacks often find inspiration in the tangible, everyday objects that surround us. Picture, if you will, a sturdy bookshelf adorned with volumes of knowledge. This visual metaphor is not just a metaphor — it’s the essence of the stack data structure, a fundamental concept in Swift programming.

The Library of LIFO

The bookshelf stands tall, each book neatly arranged, one on top of the other, forming a Last-In-First-Out (LIFO) structure. Just like in our programming world, the latest addition is the first to be explored. The stack, much like our bookshelf, embraces this principle with elegance.

Swift Implementation Magic

Let’s open the pages of Swift code to explore the implementation of a stack. In the Swift struct named Stack, the storage mirrors our bookshelf, utilizing an array for efficient insertions and deletions. It’s a simple yet powerful structure, much like the well-organized shelves in a library.

public struct Stack<Element> {
private var storage: [Element] = []
// … (other implementations)
}

Turning Pages: Push and Pop Operations

In the realm of stacks, there exist two enchanting operations: push and pop. Imagine adding a new book to the top shelf or retrieving the topmost book with a gentle pull. These operations, with their poetic simplicity, offer a delightful way of accessing and managing our literary elements.

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

@discardableResult

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

Adding a Chapter: Real-World Scenario

Now, let's bring our bookshelf to life with a real-world scenario. Imagine you're not just managing books but crafting a story with a TextEditor class:

class TextEditor {
private var content = ""
private var undoStack = [String]()

func addText(_ newText: String) {
undoStack.append(content)
content += newText
}

func undo() {
if let previousContent = undoStack.popLast() {
content = previousContent
}
}

func printContent() {
print("Current Content: \(content)")
}
}

let editor = TextEditor()
editor.addText("Hello, ")
editor.printContent() // Prints: Current Content: Hello,
editor.addText("world!")
editor.printContent() // Prints: Current Content: Hello, world!
editor.undo()
editor.printContent() // Prints: Current Content: Hello,

In this scenario, the TextEditor class uses a stack (undoStack) to manage the history of text changes. The addText function pushes the current content onto the stack before adding new text. The undo function pops the last state from the stack, allowing you to gracefully backtrack through your textual journey.

Peeking Into the Chapters: Peek and IsEmpty

Our bookshelf experience extends beyond the basics. With the peek operation, we can sneak a glance at the topmost book without disturbing the order. The isEmpty property, like an attentive librarian, lets us know if the shelves are empty or brimming with literary treasures.

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

public var isEmpty: Bool {
peek() == nil
}

Visualizing the Pages: Real-World Scenarios

As we immerse ourselves in the magic of stacks, let’s envision our bookshelf in various scenarios:

Scenario 1: Navigating Literary Worlds

In the programming realm, consider the bookshelf as an analogy for the iOS navigation stack. Each book on the shelf is akin to a view controller, with each page turned representing a push or pop operation as users navigate through the app’s literary landscapes.

// iOS navigation stack operations
navigationController?.pushViewController(nextViewController, animated: true)
navigationController?.popViewController(animated: true)

Scenario 2: Literary Memory Allocation

At the architectural level, imagine the bookshelf as the memory stack managing local variables in Swift. As we delve into a function’s narrative, new books are added (pushed), and upon conclusion, the topmost book gracefully exits (pops).

// Swift function with local variables

func enchantedFunction() {
var magicalVariable = "Abracadabra"
// magicalVariable is added to the bookshelf
// …
// magicalVariable gracefully exits when the function concludes
}

Scenario 3: Backtracking Through Literary Mazes

Picture a maze filled with literary decisions. Each turn in the maze corresponds to adding a new book to the shelf. When faced with a dead-end, we gracefully backtrack by removing books until we discover the right literary path.

// Literary maze-solving with a stack
var decisionShelf: Stack<LiteraryDirection> = [.left, .right, .straight]
// At a literary dead-end
let lastDecision = decisionShelf.pop()

In conclusion, the story of stacks unfolds as elegantly as the pages of a well-curated bookshelf. It’s not just about managing pancakes or code — it’s about orchestrating a symphony of elements in a captivating narrative.

So, the next time you encounter a stack, imagine it not just as a stack of pancakes but as a timeless library, where each literary addition and removal contributes to the enchanting tale of computational efficiency in Swift.

Happy Coding, and may your Swift journey be filled with joy and endless possibilities! 📚

--

--

Abdullah Bilgin
Swift Insights

"iOS engineer & IT head, crafting code & innovation. Leading with tech prowess & strategic vision. Bridging iOS dev & IT realms. Lifelong learner. 📱💡"