NEW: Join my free 100 Days of SwiftUI challenge today! >>

How to check whether a value is inside a range

Compare integers, dates, strings, and more

Paul Hudson       @twostraws

Most folks realize Swift’s ranges are powerful, but not enough people realize just how powerful they are - and how completely natural they can be to use.

Let’s start off with the basics. You can create a closed range like this:

let startNumber = 10
let endNumber = 100
let numberRange = startNumber...endNumber

That range is a data type just like any other, so it has methods you can use. For example, you can query whether a number lies inside the range like this:

if numberRange.contains(50) {
    print("Number is inside the range")
} else {
    print("Number is outside the range")
}

Querying range bounds like this is so common that Swift even has its own dedicated operator, ~=. It means “contains”, and it lets you use a shorter syntax if you want:

if numberRange ~= 50 {
    print("Number is inside the range")
} else {
    print("Number is outside the range")
}

Personally I prefer using contains() because it reads much more naturally, but the ~= operator has the advantage that it can be used without parentheses, like this:

if 10...100 ~= 50 {
    print("Number is inside the range")
}

To do that using contains() isn’t particularly beautiful:

if (10...100).contains(50) {
    print("Number is inside the range")
}

So far these are just regular ranges that most folks use all the time. To take things up a notch, let’s look at date ranges: you can specify a start and end date, then check whether other dates lie inside that range.

This works the same way as using integers. Start by creating a range:

let startDate = Date().addingTimeInterval(-1000)
let endDate = Date().addingTimeInterval(1000)
let dateRange = startDate...endDate

Next, pick out a test date:

let testDate = Date()

Now use contains() to figure out whether the test date lies inside the range:

if dateRange.contains(testDate) {
    print("Inside the range")
}

You can use the ~= operator here too:

if dateRange ~= testDate {
    print("Inside the range")
}

Even strings get in on this range action. So, we could define a range of strings to contain all animals that start with A through M like this:

let startAnimal = "aardvark"
let endAnimal = "mule"
let animalsAThroughM = startAnimal...endAnimal

You can then check if other animals lie inside that range like this:

if animalsAThroughM.contains("giraffe") {
    print("Giraffes are in the range!")
}

This behavior isn’t magic – it’s just a side effect of these types conforming to the Comparable protocol. This protocol is what allows you to compare integers, strings, and dates like this:

1 < 5
"abc" < "def"
firstDate < lastDate

This means if your own types also conform to Comparable they can be used as ranges too. For example, here’s a simple User struct that conforms to Comparable by comparing its lone property:

struct User: Comparable {
    var name: String

    static func < (lhs: User, rhs: User) -> Bool {
        return lhs.name < rhs.name
    }
}

We can use that to create ranges by creating two instances and combining them into a range:

let adele = User(name: "Adele")
let taylor = User(name: "Taylor")
let userRange = adele...taylor

Now we can create a test object and check whether it lies inside the range:

let paul = User(name: "Paul")

if userRange.contains(paul) {
    print("Paul is in!")
}

Because the paul instance compares as greater than adele but less than taylor, Swift considers it part of the range.

As you’ve seen, ranges are powerful in Swift partly because they can be used with several important built-in types, but also because you can use them with your own types just by conforming to Comparable!

SPONSORED Instabug helps you identify and resolve severe crashes quickly. You can retrace in-app events and know exactly which line of code caused the crash along with environment details, network logs, repro steps, and the session profiler. Ask more questions or keep users up-to-date with in-app replies straight from your dashboard. Instabug takes data privacy seriously, so no one sees your data but you! See more detailed features comparison and try Instabug's crash reporting SDK for free.

BUY OUR BOOKS
Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

About the author

Paul Hudson is the creator of Hacking with Swift, the most comprehensive series of Swift books in the world. He's also the editor of Swift Developer News, the maintainer of the Swift Knowledge Base, and a speaker at Swift events around the world. If you're curious you can learn more here.

Was this page useful? Let us know!

Average rating: 1.0/5