By mohacs


2014-06-09 22:27:01 8 Comments

lets say we have a custom class named imageFile and this class contains two properties.

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

lots of them stored in Array

var images : Array = []

var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)

aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)

question is: how can i sort images array by 'fileID' ASC or DESC?

15 comments

@GSK 2017-11-28 18:31:27

Swift 4.0, 4.1 & 4.2 First, I created mutable array of type imageFile() as shown below

var arr = [imageFile]()

Create mutable object image of type imageFile() and assign value to properties as shown below

   var image = imageFile()
   image.fileId = 14
   image.fileName = "A"

Now, append this object to array arr

    arr.append(image)

Now, assign the different properties to same mutable object i.e image

   image = imageFile()
   image.fileId = 13
   image.fileName = "B"

Now, again append image object to array arr

    arr.append(image)

Now, we will apply Ascending order on fileId property in array arr objects. Use < symbol for Ascending order

 arr = arr.sorted(by: {$0.fileId < $1.fileId}) // arr has all objects in Ascending order
 print("sorted array is",arr[0].fileId)// sorted array is 13
 print("sorted array is",arr[1].fileId)//sorted array is 14

Now, we will apply Descending order on on fileId property in array arr objects. Use > symbol for Descending order

 arr = arr.sorted(by: {$0.fileId > $1.fileId}) // arr has all objects in Descending order
 print("Unsorted array is",arr[0].fileId)// Unsorted array is 14
 print("Unsorted array is",arr[1].fileId)// Unsorted array is 13

In Swift 4.1. & 4.2 For sorted order use

let sortedArr = arr.sorted { (id1, id2) -> Bool in
  return id1.fileId < id2.fileId // Use > for Descending order
}

@Siddharth Chauhan 2018-03-14 23:16:23

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

students.sort(by: >)

print(students)

Prints : "["Peter", "Kweku", "Kofi", "Akosua", "Abena"]"

@Alex Wayne 2014-06-09 22:32:08

First, declare your Array as a typed array so that you can call methods when you iterate:

var images : [imageFile] = []

Then you can simply do:

Swift 2

images.sorted({ $0.fileID > $1.fileID })

Swift 3 & 4

images.sorted(by: { $0.fileID > $1.fileID })

The example above gives desc sort order

@mohacs 2014-06-09 22:44:12

I was missing array declaration part, it did the trick Array<imageFile>.

@GoZoner 2014-06-09 22:58:50

Using the declaration did not make a difference in my test...

@Alex Wayne 2014-06-09 23:02:18

@GoZoner that seems to make all the difference! cl.ly/image/0a162R282K1q

@GoZoner 2014-06-09 23:02:40

Ah, because I got 'type interface'... Thanks.

@mohacs 2014-06-10 00:40:38

by the way, I hope because it is beta, sort and filter performances are awful. my sample above with 1200 object in the array A..z sort gets 4 seconds. Starts 12:37:23 - Ends: 12:37:27

@Tommy 2014-07-14 18:09:32

In case it helps anybody that finds this answer: I found this answer independently by consulting the Swift Standard Library Reference — developer.apple.com/library/prerelease/ios/documentation/…

@Isuru 2014-09-28 16:34:39

@AlexWayne I have a NSManagedObject subclass called CheckInAndOut. And in a separate file, I've declared a typed array for objects of this type and when I try to sort it, I get a Could not find member error. Any idea why this is?

@Isuru 2014-11-10 18:02:01

I found my problem. Apparently the array wasn't a typed array. Anyway I have a new issue. How can I sort an array by multiple properties? Say I have 2 properties like firstName and lastName in an array of Person objects. First I want to sort it by firstName and then lastName. How I can I do this?

@Taylor M 2015-09-30 21:21:10

do you now need to do images.sortInPlace({ $0.fileID > $1.fileID })?

@cmario 2015-12-09 16:22:59

can i add a third comparison into the same line?

@Danny Wang 2016-04-04 07:21:32

in case anyone is wondering the same: the answer will give desc order

@Kevin 2017-01-12 08:16:29

It has been replaced by sorted function.

@jnblanchard 2017-12-19 04:35:30

Swift 2 through 4

The original answer sought to sort an array of custom objects using some property. Below I will show you a few handy ways to do this same behavior w/ swift data structures!

Little things outta the way, I changed ImageFile ever so slightly. With that in mind, I create an array with three image files. Notice that metadata is an optional value, passing in nil as a parameter is expected.

 struct ImageFile {
      var name: String
      var metadata: String?
      var size: Int
    }

    var images: [ImageFile] = [ImageFile(name: "HelloWorld", metadata: nil, size: 256), ImageFile(name: "Traveling Salesmen", metadata: "uh this is huge", size: 1024), ImageFile(name: "Slack", metadata: "what's in this stuff?", size: 2048) ]

ImageFile has a property named size. For the following examples I will show you how to use sort operations w/ properties like size.

smallest to biggest size (<)

    let sizeSmallestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size < next.size
    }

biggest to smallest (>)

    let sizeBiggestSorted = images.sorted { (initial, next) -> Bool in
      return initial.size > next.size
    }

Next we'll sort using the String property name. In the same manner, use sort to compare strings. But notice the inner block returns a comparison result. This result will define sort.

A-Z (.orderedAscending)

    let nameAscendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedAscending
    }

Z-A (.orderedDescending)

    let nameDescendingSorted = images.sorted { (initial, next) -> Bool in
      return initial.name.compare(next.name) == .orderedDescending
    }

Next is my favorite way to sort, in many cases one will have optional properties. Now don't worry, we're going to sort in the same manner as above except we have to handle nil! In production;

I used this code to force all instances in my array with nil property values to be last. Then order metadata using the assumed unwrapped values.

    let metadataFirst = images.sorted { (initial, next) -> Bool in
      guard initial.metadata != nil else { return true }
      guard next.metadata != nil else { return true }
      return initial.metadata!.compare(next.metadata!) == .orderedAscending
    }

It is possible to have a secondary sort for optionals. For example; one could show images with metadata and ordered by size.

@Tom Aranda 2017-12-19 05:03:18

Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others.

@jnblanchard 2017-12-19 15:50:25

@TomAranda thanks tom, hopefully this helps others.

@Tom Aranda 2017-12-19 16:01:47

Much much better.

@Illya Krit 2017-09-26 14:02:07

I do it like this and it works:

var images = [imageFile]() images.sorted(by: {$0.fileID.compare($1.fileID) == .orderedAscending })

@Imanou Petit 2015-12-02 20:14:02

With Swift 4, Array has two methods called sorted() and sorted(by:). The first method, sorted(), has the following declaration:

Returns the elements of the collection, sorted.

func sorted() -> [Element]

The second method, sorted(by:), has the following declaration:

Returns the elements of the collection, sorted using the given predicate as the comparison between elements.

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

1. Sort with ascending order for comparable objects

If the element type inside your collection conforms to Comparable protocol, you will be able to use sorted() in order to sort your elements with ascending order. The following Playground code shows how to use sorted():

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

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

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted()
print(sortedImages)

/*
 prints: [ImageFile with ID: 100, ImageFile with ID: 200, ImageFile with ID: 300]
 */

2. Sort with descending order for comparable objects

If the element type inside your collection conforms to Comparable protocol, you will have to use sorted(by:) in order to sort your elements with a descending order.

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

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

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0 > img1
})
//let sortedImages = images.sorted(by: >) // also works
//let sortedImages = images.sorted { $0 > $1 } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

3. Sort with ascending or descending order for non-comparable objects

If the element type inside your collection DOES NOT conform to Comparable protocol, you will have to use sorted(by:) in order to sort your elements with ascending or descending order.

class ImageFile: CustomStringConvertible {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0.fileID < img1.fileID
})
//let sortedImages = images.sorted { $0.fileID < $1.fileID } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

Note that Swift also provides two methods called sort() and sort(by:) as counterparts of sorted() and sorted(by:) if you need to sort your collection in-place.

@Lars Petersen 2018-01-14 22:18:24

This is an excellent answer! Thank you so much!

@jaiswal Rajan 2017-01-07 16:39:04

In Swift 3.0

images.sort(by: { (first: imageFile, second: imageFile) -> Bool in
    first. fileID < second. fileID
})

@Bernauer 2015-12-22 08:43:57

Two alternatives

1) Ordering the original array with sortInPlace

self.assignments.sortInPlace({ $0.order < $1.order })
self.printAssignments(assignments)

2) Using an alternative array to store the ordered array

var assignmentsO = [Assignment] ()
assignmentsO = self.assignments.sort({ $0.order < $1.order })
self.printAssignments(assignmentsO)

@Hermann Klecker 2016-01-22 23:35:40

re 2) What is the point in constructing an empty array and discarding it in the very next line? I'd sugest using var assignmentsO : [Assignment] or combine it into one line by using let assignmentsO = self.assignments.sort({ $0.order < $1.order })

@Bernauer 2016-01-24 16:30:58

Hi Hermann! There is a very thin line between writing readable and efficient code. In this case, the only point is making it more readable to the community ;) enjoy!

@quemeful 2016-09-28 19:57:05

Swift 3

people = people.sorted(by: { $0.email > $1.email })

@Ebru Güngör 2016-11-20 21:29:42

i have tried this with a date comparison, could not get it working. Any idea?

@quemeful 2016-11-20 22:37:46

What format were the dates in? String, NSDate?

@Ebru Güngör 2016-11-20 22:42:32

Not NSDate or String, current swift 3 Date object.

@quemeful 2016-11-20 22:46:21

Which property of Date are you comparing? The property must be able to be compared with the function used (greater than in my example)

@Fattie 2017-01-03 16:24:02

This is the only useful answer for 2017 onwards.

@Leo Dabus 2018-08-26 18:26:57

@Fattie What do you mean? The correct syntax is people.sort { $0.email > $1.email }

@Leo Dabus 2018-08-26 18:34:39

I wonder how this answer got 39 upvotes

@Fattie 2018-08-27 02:57:59

quite right @LeoDabus , good one! In the old days, the previous answers were rubbish.

@GoZoner 2014-06-09 22:30:00

[Updated for Swift 3 with sort(by:)] This, exploiting a trailing closure:

images.sorted { $0.fileID < $1.fileID }

where you use < or > depending on ASC or DESC, respectively. If you want to modify the images array, then use the following:

images.sort { $0.fileID < $1.fileID }

If you are going to do this repeatedly and prefer to define a function, one way is:

func sorterForFileIDASC(this:imageFile, that:imageFile) -> Bool {
  return this.fileID > that.fileID
}

and then use as:

images.sort(by: sorterForFileIDASC)

@Muneef M 2015-11-28 20:57:03

how can i sue this with string? i need to sort string by its length

@Surjeet Rajput 2016-08-30 10:33:04

@MuneefM just return string1.length < string2.length

@Crashalot 2016-09-24 08:46:00

sort no longer compiles with this syntax in Xcode 8. Xcode 8 says $0.fileID < $1.fileID produces a Bool not ComparisonResult.

@GoZoner 2016-09-24 14:54:44

This answer's code works fine in Xcode8; if you've got a error, post a new question.

@fujianjin6471 2015-04-19 14:36:29

Nearly everyone gives how directly, let me show the evolvement:

you can use the instance methods of Array:

// general form of closure
images.sortInPlace({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })

// types of closure's parameters and return value can be inferred by Swift, so they are omitted along with the return arrow (->)
images.sortInPlace({ image1, image2 in return image1.fileID > image2.fileID })

// Single-expression closures can implicitly return the result of their single expression by omitting the "return" keyword
images.sortInPlace({ image1, image2 in image1.fileID > image2.fileID })

// closure's argument list along with "in" keyword can be omitted, $0, $1, $2, and so on are used to refer the closure's first, second, third arguments and so on
images.sortInPlace({ $0.fileID > $1.fileID })

// the simplification of the closure is the same
images = images.sort({ (image1: imageFile, image2: imageFile) -> Bool in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in return image1.fileID > image2.fileID })
images = images.sort({ image1, image2 in image1.fileID > image2.fileID })
images = images.sort({ $0.fileID > $1.fileID })

For elaborate explanation about the working principle of sort, see The Sorted Function.

@Hanny 2015-12-13 11:55:42

If you want to sort original array of custom objects. Here is another way to do so in Swift 2.1

var myCustomerArray = [Customer]()
myCustomerArray.sortInPlace {(customer1:Customer, customer2:Customer) -> Bool in
    customer1.id < customer2.id
}

Where id is an Integer. You can use the same < operator for String properties as well.

You can learn more about its use by looking at an example here: Swift2: Nearby Customers

@dorian 2015-08-11 18:10:13

If you are not using custom objects, but value types instead that implements Comparable protocol (Int, String etc..) you can simply do this:

myArray.sort(>) //sort descending order

An example:

struct MyStruct: Comparable {
    var name = "Untitled"
}

func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name < rhs.name
}
// Implementation of == required by Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()

value2.name = "A New Name"

var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)

anArray.sort(>) // This will sort the array in descending order

@beryllium 2017-04-13 11:01:40

in swift 3 it's myArray.sorted(by: >)

@kwerle 2015-04-17 18:48:53

If you are going to be sorting this array in more than one place, it may make sense to make your array type Comparable.

class MyImageType: Comparable, Printable {
    var fileID: Int

    // For Printable
    var description: String {
        get {
            return "ID: \(fileID)"
        }
    }

    init(fileID: Int) {
        self.fileID = fileID
    }
}

// For Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID < right.fileID
}

// For Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID == right.fileID
}

let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)

let a1 = [one, three, two]

// return a sorted array
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"

var a2 = [two, one, twoA, three]

// sort the array 'in place'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"

@Nicolas Grenié 2014-06-12 04:54:20

You can also do something like

images = sorted(images) {$0.fileID > $1.fileID}

so your images array will be stored as sorted

Related Questions

Sponsored Content

76 Answered Questions

[SOLVED] How do I remove a particular element from an array in JavaScript?

  • 2011-04-23 22:17:18
  • Walker
  • 5492496 View
  • 6814 Score
  • 76 Answer
  • Tags:   javascript arrays

25 Answered Questions

[SOLVED] Sort ArrayList of custom Objects by property

43 Answered Questions

[SOLVED] How to check if an object is an array?

9 Answered Questions

[SOLVED] Swift Beta performance: sorting arrays

44 Answered Questions

26 Answered Questions

[SOLVED] Sorting an array of JavaScript objects

30 Answered Questions

[SOLVED] How to append something to an array?

41 Answered Questions

[SOLVED] How do I sort a dictionary by value?

39 Answered Questions

[SOLVED] Sort array of objects by string property value

25 Answered Questions

[SOLVED] How do I sort an NSMutableArray with custom objects in it?

Sponsored Content