Swift: Sort array of objects alphabetically

前端 未结 7 1050
梦如初夏
梦如初夏 2020-12-12 12:20

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 trie

相关标签:
7条回答
  • 2020-12-12 12:44

    Sorted array Swift 4.2

    arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })
    
    0 讨论(0)
  • 2020-12-12 12:47

    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)
    
    0 讨论(0)
  • 2020-12-12 12:54

    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]
     */
    
    0 讨论(0)
  • 2020-12-12 12:56

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

    movieArr.sorted { $0.Name < $1.Name }
    
    0 讨论(0)
  • 2020-12-12 12:56

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

    0 讨论(0)
  • 2020-12-12 12:57
    let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
    
    0 讨论(0)
提交回复
热议问题