5 very useful functions from Swift Algorithms


You’re more of a video kind of person? I’ve got you covered! Here’s a video with the same content than this article 🍿


Advertisement

Product for Engineers is PostHog's newsletter helping engineers flex their product muscle.

It covers curated advice on building great products, lessons (and mistakes) from building PostHog, deep dives into the strategies of top startups, and more.

👉 Subscribe for free 👈


Sponsors like PostHog really help me grow my content creation, so if you have time please make sure to check out their survey: it’s a direct support to my content creation ☺️


In this article, I want to tell you about a very useful package called Swift Algorithms!

Swift Algorithms is an official package published by the Swift team, that contains useful methods for when you’re working with sequences and collections.

And while this package does contain some very specific methods that most iOS developers will probably never need to use…

…it also contains some very useful helper functions that solve problems many iOS developers will be facing!

So I made a top 5 of the functions in this package that all iOS developers should be aware of!

#01 – .chunks(ofCount:)

If you ever need to implement pagination in your app, the method chunks(ofCount:) will be very useful!

You can use it to split a Collection into chunks of a given size or based on a predicate.

Alternatively, you can also indicate how many chunks you want and let it split the elements appropriately.

#02 – .randomSample()

This function allows you to take a random sample of a Sequence or a Collection.

If you’ve ever had to implement random sampling yourself, you know how easy it is to mistakenly introduce bias in the selection.

So being able to rely on an official implementation is quite welcome!

#03 – .indexed()

indexed() works in a very similar way to the function enumerated(), except that whereas enumerated() returns an increasing count, indexed() will return the actual indices of the elements.

Which means that you can in turn safely use these indices to subscript the original Collection, without the risk of causing a crash at runtime.

#04 – .min(count:) & .max(count:)

These functions are very useful if you ever need to retrieve only the N smallest or largest elements from a large Sequence, because they don’t need to fully sort the original Sequence to return their result, which makes them run faster.

#05 – .compacted(), .firstNonNil() & .uniqued()

I chose these 3 functions because they all solve a very basic and common problem, and so there’s a good chance that you’ve already implemented one of them yourself!

But if you prefer, you can choose to use the implementation of the Swift Algorithms package instead, which has the advantage of being thoroughly tested and optimized!


And that’s it, we’ve reached the end of this top 5!

I’ve only showed you a glimpse of what the Swift Algorithms package contains, so I would really recommend that you take two minutes to read its full list of features: maybe you’ll find something that can help you save a lot of time and energy!

If you want, I can even walk you through it: last week I went over the entire content of the package during a livestream!

Here’s the code if you want to experiment with it:

import Algorithms

// .chunks(ofCount:)

let names = ["David", "Kyle", "Karoy", "Nate"]
let evenly = names.chunks(ofCount: 2)
// equivalent to [["David", "Kyle"], ["Karoy", "Nate"]]

let numbers = [10, 20, 30, 10, 40, 40, 10, 20]
let chunks = numbers.chunked(by: { $0 <= $1 })
// [[10, 20, 30], [10, 40, 40], [10, 20]]

let evenChunks = (0..<15).evenlyChunked(in: 3)
// equivalent to [0..<5, 5..<10, 10..<15]

// .randomSample()

var source = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]

let sample = source.randomSample(count: 4)
// e.g. [30, 10, 70, 50]

// .indexed()

let numbers = [10, 20, 30, 40, 50]
var matchingIndices: Set<Int> = []
for (i, n) in numbers.indexed() {
    if n.isMultiple(of: 20) {
        matchingIndices.insert(i)
    }
}
// matchingIndices == [1, 3]

// .min(count:) & .max(count:)

let numbers = [7, 1, 6, 2, 8, 3, 9]
let smallestThree = numbers.min(count: 3, sortedBy: <)
// [1, 2, 3]

let biggestThree = numbers.max(count: 3, sortedBy: <)
// [7, 8, 9]

// .compacted(), .firstNonNil() & .uniqued()

let array: [Int?] = [10, nil, 30, nil, 2, 3, nil, 5]
let withNoNils = array.compacted()
// Array(withNoNils) == [10, 30, 2, 3, 5]

let strings = ["three", "3.14", "-5", "2"]
if let firstInt = strings.firstNonNil({ Int($0) }​) {
    print(firstInt)
    // -5
}

let numbers = [1, 2, 3, 3, 2, 3, 3, 2, 2, 2, 1]
let unique = numbers.uniqued()
// Array(unique) == [1, 2, 3]
Previous
Previous

How to help someone get started with iOS engineering 👩🏽‍💻👨🏻‍💻

Next
Next

How to run native code from a WKWebView