How to Filter an Array in Swift

To filter an array in Swift:

  1. Call the Array.filter() method on an array.
  2. Pass a filtering function as an argument to the method.

For instance, let’s filter an array of words such that only words less than 4 characters long remain:

let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

let filtered = words.filter { $0.count < 4 }

print(filtered)

Output:

["Is", "But", "A"]

This is the quick answer. But to know how filtering really works in Swift, please read along.

How to Filter an Array in Swift

In the introduction, you saw a simple example where you filter an array of strings by length. But how does it work? How could you filter something else, such as an array of objects?

Let’s take a more detailed tour of filtering arrays in Swift. Our goal is to understand the above example by starting from the basics.

For Loop Filtering in Swift

First of all, let’s take a look at a naive approach to filtering an array using a for loop. When you filter an array with a for loop, you:

  1. Go through each element in the array.
  2. Check if each element satisfies a condition.
  3. Add items that satisfy the condition to the result array.
  4. When each element is examined this way, you are left with the filtered array.

For example, let’s use a for loop to filter an array of words less than 4 characters in length:

let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

var filtered: [String] = []

// 1. Go through each element
for word in words {
  // Check if an element satisfies a condition
  if word.count < 4 {
    // Add an element that passes the check to a result array
    filtered.append(word)
  }
}

// 4. After the loop, you can display your result array of filtered items.
print(filtered)

Output:

["Is", "But", "A"]

This piece of code works fine. But if you want to save lines of code, you can use shorthand. This shorthand is the Array.filter() method.

Array.filter() Method in Swift

The Array.filter() method in Swift takes a filtering function as its argument and produces a new array. Here is how it works:

  1. It applies the filtering function for each element in the array.
  2. If an element passes the check, the element is added to a result array.
  3. Finally, it returns the result array after looping through each element.

To use the Array.filter() method in Swift, you need two things:

  1. An array of elements
  2. A filtering function.

With these two you can call the filter() method on the array.

To demonstrate, let’s filter an array of words less than 4 characters in length:

1. Creating an array of strings is trivial:

let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

2. Then you need to implement the filtering function. In this case, you create a function that checks if a string is less than 4 characters in length. Thus the filtering function should take a string as its input, and spit out a boolean.

This is also trivial to implement:

func lessThanFour(word: String) -> Bool {
  return word.count < 4
}

Now you have an array of elements and a filtering function. This means you can call the Array.filter() to filter the words.

Here is the code:

// 1. Define an array of strings
let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

// 2. Define the filtering function
func lessThanFour(word: String) -> Bool {
  return word.count < 4
}


// Call the filtering function
let filtered = words.filter(lessThanFour)

print(filtered)

Output:

["Is", "But", "A"]

Awesome! Now you understand how the Array.filter() method works.

Best Practices

Let’s next talk about best practices.

Imagine you are using the above code in your project only once. After you have successfully filtered an array of strings, the function lessThanFour becomes useless. You only needed it for one task, but it stays in your code forever.

To write cleaner code, you should avoid having useless methods and functions in your codebase.

But how? If you define a function, you cannot delete it, right?

To write a “one-time-only” function, you should use closures instead of regular functions.

Closures and Filtering in Swift

A closure is an anonymous function that is passed as an argument into a function/method call.

A closure is defined directly in the function call so no separate function is needed. When the closure is used, there will be no trace of it.

Let’s continue with the previous example, where we filter an array of words that are less than 4 characters in length.

This time, let’s not define a separate filtering function. Instead, let’s use a closure that you can define directly into the Array.filter() call.

let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

let filtered = words.filter{ word in
  return word.count < 4
}

print(filtered)

Output:

["Is", "But", "A"]

Now there is no separate filtering function anymore. Instead, the function is defined in the block of code right after the filter call. This is a closure function that acts as the filtering function.

  • The word in part means this closure function takes one argument.
  • The return word.count < 4 is the actual function behavior that checks if the word has less than 4 characters.

Now you understand how you can define a closure function in Array.filter() method call.

But we are not there yet. There is actually a shorthand for closures as well.

$0 in Swift Closures

Instead of defining a lengthy closure function on multiple lines, you can use the $0 notation. The $0 refers to the “first argument” in a closure function. You can directly use this parameter in a closure function and completely omit the word in part at the beginning for example.

Let’s apply this notation to make the code in the previous example shorter and cleaner:

let words = ["Hello", "This", "Is", "Nothing", "But", "A", "Test"]

let filtered = words.filter { $0.count < 4 }

print(filtered)

Output:

["Is", "But", "A"]

Amazing! Now the piece of code is really short and concise and it is easy to see what the intention is.

This is how you transformed a for loop filtering functionality into a neat one-liner filter() call.

Now let’s apply this knowledge on a slightly more advanced task.

How to Filter an Array of Objects in Swift

Now that you understand how basic filtering works in Swift, you can apply the knowledge to filter an array of objects.

For example, given a student class:

class Student {
    let name: String
    init(name: String) {
        self.name = name
    }
}

And an array of students:

let s1 = Student(name: "Alice")
let s2 = Student(name: "Bob")
let s3 = Student(name: "Charlie")

let students = [s1, s2, s3]

Your task is to filter the array of students such that only students with the letter “L” in their name are left.

To pull this off, let’s call the Array.filter() on the array of students. This time let’s pass it a closure that checks if the name contains letter “L”.

To refer to each Student object in the filter() call, you can simply use the $0 parameter.

Here is the solution:

let namesWithL = students.filter{ $0.name.contains("l") }

for student in namesWithL {
  print(student.name)
}

Output:

Alice
Charlie

To recap, the filter() method checks each Student object’s name property whether it has letter “L” or not. If it has, the student stays in the result array.

For your convenience, here is the full code:

class Student {
    let name: String
    init(name: String) {
        self.name = name
    }
}

let s1 = Student(name: "Alice")
let s2 = Student(name: "Bob")
let s3 = Student(name: "Charlie")

let students = [s1, s2, s3]

let namesWithL = students.filter{ $0.name.contains("l") }

for student in namesWithL {
  print(student.name)
}

Conclusion

In Swift, you can filter an array using the Array.filter() method. To do this, you need:

  1. An array of elements.
  2. A filtering function.
  3. Call Array.filter() on the array of elements with the filtering function.

Even though you can write a separate filtering function, it is advisable to use a closure. This means you define an anonymous function directly into the Array.filter() call. This function then acts as the filtering function and is applied to each element in the array.

Thanks for reading. I hope you liked it.

Happy coding!

Further Reading

50 Swift Interview Questions

iOS Development Tips

Share on facebook
Share on twitter
Share on linkedin

Leave a Comment

Your email address will not be published.