This article will show you how to sort an array of custom objects by property value in Swift.
Sorting an array of custom objects by a property value is a common task in Swift. Whether your objects conform to the Comparable
protocol or not, Swift provides several ways to achieve this.
Declare Typed Array
Before sorting, you need to declare your array as a typed array. This means specifying the type of objects the array will contain. In this case, it’s an array of ImageFile
objects:
var images: [ImageFile] = []
This line initializes an empty array that can only hold objects of type ImageFile
.
Sort with Comparable Objects
When your custom object conforms to the Comparable
protocol, you can leverage Swift’s built-in sorting methods for a more straightforward sorting process.
Ascending Order:
If your ImageFile
class implements the Comparable
protocol by defining the <
operator, you can use the sorted()
method:
let sortedImages = images.sorted()
In this line, the images
array is sorted in ascending order based on the default comparison defined in the <
operator of the ImageFile
class.
Descending Order:
To sort in descending order, you can use the sorted(by:)
method with a closure:
let sortedImagesDescending = images.sorted(by: { $0.fileID > $1.fileID })
This line sorts the images
array in descending order based on the fileID
property. The closure compares fileID
values, determining the order of the sorted array.
In both cases, sorting is done using the natural order defined by the Comparable
protocol, and the resulting array is assigned to the sortedImages
or sortedImagesDescending
constant.
Sort with Non-Comparable Objects
When your custom object does not conform to the Comparable
protocol, you need to use the sorted(by:)
method with a closure to define the sorting criteria.
Ascending Order:
If the ImageFile
class does not implement the Comparable
protocol, you can use the sorted(by:)
method with a closure for ascending order:
let sortedImages = images.sorted(by: { $0.fileID < $1.fileID })
In this line, the images
array is sorted in ascending order based on the fileID
property. The closure compares fileID
values, determining the order of the sorted array.
Descending Order:
For descending order, use the sorted(by:)
method with a closure that compares the properties in reverse order:
let sortedImagesDescending = images.sorted(by: { $0.fileID > $1.fileID })
This line sorts the images
array in descending order based on the fileID
property. The closure compares fileID
values, determining the order of the sorted array.
In both cases, the sorted(by:)
method allows you to customize the sorting criteria using a closure, providing flexibility for non-comparable objects. The resulting array is assigned to the sortedImages
or sortedImagesDescending
constant.
Sort Using a Function
If you prefer defining a separate function for sorting, you can do so. In this example, a function sorterForFileIDASC
is defined:
func sorterForFileIDASC(this: ImageFile, that: ImageFile) -> Bool { return this.fileID < that.fileID } // Sort in ascending order images.sort(by: sorterForFileIDASC)
This function takes two ImageFile
objects and returns a Bool
indicating whether the first object should come before the second in the sorted order. The images.sort(by:)
method is then used to sort the array using this function.
Swift 5 KeyPathComparator
Swift 5 introduces KeyPathComparator
for dynamic comparisons. This example demonstrates sorting based on different key paths with specified ordering:
files = files.sorted(using: [ KeyPathComparator(\.fileID, order: .forward), KeyPathComparator(\.fileSize, order: .reverse), ])
Here, the files
array is sorted first in ascending order based on the fileID
key path, and ties are broken in descending order based on the fileSize
key path.
These methods offer various approaches to sorting an array of custom objects in Swift, depending on the conformance to the Comparable
protocol and the specific sorting criteria you need.