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.
7 Answers 7
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)
}
-
1use movies.sort instead of movies.sorted @Mike Suser2707185– user270718511/04/2015 11:22:53Commented Nov 4, 2015 at 11:22
-
@julian-król You forgot to edit the other
sorted
tosort
in the answer. Note: this is not a typo,sorted
was correct in Swift 1 but has becomesort
in Swift 2.Eric Aya– Eric Aya12/03/2015 10:47:22Commented Dec 3, 2015 at 10:47 -
1thanks for explanation. Improved my edit, should be fine, please take a look :)Julian– Julian12/03/2015 10:56:38Commented Dec 3, 2015 at 10:56
-
12Beware, this won't work when sorting string that may or may not be capitalized. Comparing the
.lowercaseString
will solve this problem.Matthieu Riegler– Matthieu Riegler02/26/2016 14:41:19Commented Feb 26, 2016 at 14:41 -
2@EricAya Note it is
sorted
in Swift 3 again :D .dvp.petrov– dvp.petrov12/09/2016 15:44:38Commented Dec 9, 2016 at 15:44
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]
*/
-
Hey, Is there any diff. between 2nd and 3rd (except
movies.sorted(by: <)
andmovies.sorted()
) ?Kamaldeep singh Bhatia– Kamaldeep singh Bhatia12/15/2017 11:10:01Commented Dec 15, 2017 at 11:10 -
sorted(by:)
andsorted()
are two different methods. You can usearray.sorted()
as an alternative forarray.sorted(by: <)
.Imanou Petit– Imanou Petit12/15/2017 11:17:52Commented Dec 15, 2017 at 11:17 -
Yes, just asking in case of class definition do we need to change anything? I mean, can we have same class definition for both
sorted(by:)
andsorted()
?Kamaldeep singh Bhatia– Kamaldeep singh Bhatia12/15/2017 11:26:34Commented Dec 15, 2017 at 11:26 -
1Yes, you can have the same implementation of your class/struct that, in any case, has to conform to
Comparable
protocol.Imanou Petit– Imanou Petit12/15/2017 16:02:20Commented Dec 15, 2017 at 16:02 -
I have Array with customObject when i shoer in ascending order it's not shorting in proper way.
"1" "14""28""31""4""42""49"
Krunal Nagvadia– Krunal Nagvadia08/17/2019 10:53:50Commented Aug 17, 2019 at 10:53
let sortArray = array.sorted(by: { 0ドル.name.lowercased() < 1ドル.name.lowercased() })
-
adding .lowercased() worked for me after a long period of trying. I don't understand why, since all text were lowercased to begin with.Tom Tallak Solbu– Tom Tallak Solbu12/17/2018 18:59:55Commented Dec 17, 2018 at 18:59
-
when use lowercased() will change all names to lower case to sorted properly :)Marwan Alqadi– Marwan Alqadi12/18/2018 07:26:43Commented Dec 18, 2018 at 7:26
For those using Swift 3, the equivalent method for the accepted answer is:
movieArr.sorted { 0ドル.Name < 1ドル.Name }
Most of these answers are wrong due to the failure to use a locale based comparison for sorting. Look at localizedStandardCompare()
Sorted array Swift 4.2
arrayOfRaces = arrayOfItems.sorted(by: { (0ドル["raceName"] as! String) < (1ドル["raceName"] as! String) })
*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!
}*