Swift: Sort array of objects alphabetically

IosArraysSwiftSorting

Ios Problem Overview


I have this:

class Movies {
  Name:String
  Date:Int
}

and an array of [Movies]. How do I sort the array alphabetically by name? I've tried:

movieArr = movieArr.sorted{ $0 < $1 }

and

movieArr = sorted(movieArr)

but that doesn't work because I'm not accessing the name attribute of Movies.

Ios Solutions


Solution 1 - Ios

In the closure you pass to sort, compare the properties you want to sort by. Like this:

movieArr.sorted { $0.name < $1.name }

or the following in the cases that you want to bypass cases:

movieArr.sorted { $0.name.lowercased() < $1.name.lowercased() }

Sidenote: Typically only types start with an uppercase letter; I'd recommend using name and date, not Name and Date.


Example, in a playground:

class Movie {
    let name: String
    var date: Int?
    
    init(_ name: String) {
        self.name = name
    }
}

var movieA = Movie("A")
var movieB = Movie("B")
var movieC = Movie("C")

let movies = [movieB, movieC, movieA]
let sortedMovies = movies.sorted { $0.name < $1.name }
sortedMovies

sortedMovies will be in the order [movieA, movieB, movieC]

> Swift5 Update

channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
            let channelName1 = channel1.name
            let channelName2 = channel2.name
            return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)

Solution 2 - Ios

With Swift 3, you can choose one of the following ways to solve your problem.


1. Using sorted(by:​) with a Movie class that does not conform to Comparable protocol

If your Movie class does not conform to Comparable protocol, you must specify in your closure the property on which you wish to use Array's sorted(by:​) method.

Movie class declaration:

import Foundation

class Movie: CustomStringConvertible {

    let name: String
    var date: Date
    var description: String { return name }

    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }
    
}

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0.name < $1.name })
// let sortedMovies = movies.sorted { $0.name < $1.name } // also works

print(sortedMovies)

/*
prints: [Avatar, Piranha II: The Spawning, Titanic]
*/

2. Using sorted(by:​) with a Movie class that conforms to Comparable protocol

However, by making your Movie class conform to Comparable protocol, you can have a much concise code when you want to use Array's sorted(by:​) method.

Movie class declaration:

import Foundation

class Movie: CustomStringConvertible, Comparable {
    
    let name: String
    var date: Date
    var description: String { return name }
    
    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

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

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted(by: { $0 < $1 })
// let sortedMovies = movies.sorted { $0 < $1 } // also works
// let sortedMovies = movies.sorted(by: <) // also works

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

3. Using sorted() with a Movie class that conforms to Comparable protocol

By making your Movie class conform to Comparable protocol, you can use Array's sorted() method as an alternative to sorted(by:​).

Movie class declaration:

import Foundation

class Movie: CustomStringConvertible, Comparable {
    
    let name: String
    var date: Date
    var description: String { return name }
    
    init(name: String, date: Date = Date()) {
        self.name = name
        self.date = date
    }

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

Usage:

let avatarMovie = Movie(name: "Avatar")
let titanicMovie = Movie(name: "Titanic")
let piranhaMovie = Movie(name: "Piranha II: The Spawning")

let movies = [avatarMovie, titanicMovie, piranhaMovie]
let sortedMovies = movies.sorted()

print(sortedMovies)

/*
 prints: [Avatar, Piranha II: The Spawning, Titanic]
 */

Solution 3 - Ios

let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })

Solution 4 - Ios

For those using Swift 3, the equivalent method for the accepted answer is:

movieArr.sorted { $0.Name < $1.Name }

Solution 5 - Ios

Most of these answers are wrong due to the failure to use a locale based comparison for sorting. Look at localizedStandardCompare()

Solution 6 - Ios

Sorted array Swift 4.2

arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })

Solution 7 - Ios

*import Foundation
import CoreData


extension Messages {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Messages> {
        return NSFetchRequest<Messages>(entityName: "Messages")
    }

    @NSManaged public var text: String?
    @NSManaged public var date: Date?
    @NSManaged public var friends: Friends?

}

    //here arrMessage is the array you can sort this array as under bellow 
    
    var arrMessages = [Messages]()
    
    arrMessages.sort { (arrMessages1, arrMessages2) -> Bool in
               arrMessages1.date! > arrMessages2.date!
    }*

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJonah RufferView Question on Stackoverflow
Solution 1 - IosMike SView Answer on Stackoverflow
Solution 2 - IosImanou PetitView Answer on Stackoverflow
Solution 3 - IosMarwan AlqadiView Answer on Stackoverflow
Solution 4 - IosJacobo KoenigView Answer on Stackoverflow
Solution 5 - IosEricView Answer on Stackoverflow
Solution 6 - IosSrinivasan_iOSView Answer on Stackoverflow
Solution 7 - IosMuhammad AhmadView Answer on Stackoverflow