Schnell: Sortieren Sie das Array von Objekten alphabetisch

136

Ich habe das:

class Movies {
  Name:String
  Date:Int
}

und eine Reihe von [Filmen]. Wie sortiere ich das Array alphabetisch nach Namen? Ich habe es versucht:

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

und

movieArr = sorted(movieArr)

Aber das funktioniert nicht, weil ich nicht auf das Namensattribut von Filmen zugreife.

Jonah Ruffer
quelle

Antworten:

295

sortVergleichen Sie in dem Abschluss, an den Sie übergeben , die Eigenschaften, nach denen Sie sortieren möchten. So was:

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

oder Folgendes in den Fällen, in denen Sie Fälle umgehen möchten:

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

Nebenbemerkung: Normalerweise beginnen nur Typen mit einem Großbuchstaben. Ich würde empfehlen, nameund date, nicht Nameund zu verwenden Date.


Beispiel auf einem Spielplatz:

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 wird in der Reihenfolge sein [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)
Mike S.
quelle
Danke, ich fange gerade mit Swift an und wusste nichts über die Verwendung von Verschlüssen.
CDPALMER
1
Verwenden Sie movies.sort anstelle von movies.sorted @Mike S
Oskariagon
1
Danke für die Erklärung. Verbesserte meine Bearbeitung, sollte in Ordnung sein, bitte werfen Sie einen Blick :)
Julian Król
8
Beachten Sie, dass dies beim Sortieren von Zeichenfolgen, die möglicherweise groß geschrieben werden oder nicht, nicht funktioniert. Ein Vergleich der .lowercaseStringwird dieses Problem lösen.
Matthieu Riegler
2
@EricAya Beachten Sie, dass es wieder sortedin Swift 3 ist: D.
dvp.petrov
44

Mit Swift 3 können Sie eine der folgenden Möglichkeiten wählen, um Ihr Problem zu lösen.


1. Verwenden sorted(by:​)mit einer MovieKlasse, die nicht dem ComparableProtokoll entspricht

Wenn Ihre MovieKlasse nicht dem ComparableProtokoll entspricht, müssen Sie in Ihrem Abschluss die Eigenschaft angeben, für die Sie die Array- sorted(by:​)Methode verwenden möchten .

Movie Klassendeklaration:

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
    }

}

Verwendung:

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. Verwenden sorted(by:​)mit einer MovieKlasse, die dem ComparableProtokoll entspricht

Wenn Sie Ihre MovieKlasse jedoch an das ComparableProtokoll anpassen , können Sie einen sehr präzisen Code haben, wenn Sie die Array- sorted(by:​)Methode verwenden möchten .

Movie Klassendeklaration:

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
    }

}

Verwendung:

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. Verwenden sorted()mit einer MovieKlasse, die dem ComparableProtokoll entspricht

Indem Sie Ihre MovieKlasse an das ComparableProtokoll anpassen , können Sie sorted()alternativ die Array- Methode verwenden sorted(by:​).

Movie Klassendeklaration:

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
    }

}

Verwendung:

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]
 */
Imanou Petit
quelle
Hey, gibt es einen Unterschied? zwischen 2. und 3. (außer movies.sorted(by: <)und movies.sorted())?
Kamaldeep singh Bhatia
sorted(by:)und sorted()sind zwei verschiedene Methoden. Sie können array.sorted()als Alternative für verwenden array.sorted(by: <).
Imanou Petit
Ja, wenn wir nur nach einer Klassendefinition fragen, müssen wir etwas ändern? Ich meine, können wir für beide sorted(by:)und dieselbe Klassendefinition haben sorted()?
Kamaldeep singh Bhatia
1
Ja, Sie können dieselbe Implementierung Ihrer Klasse / Struktur verwenden, die in jedem Fall dem ComparableProtokoll entsprechen muss.
Imanou Petit
Ich habe Array mit customObject, wenn ich in aufsteigender Reihenfolge shoer, es ist nicht in der richtigen Weise Kurzschluss. "1" "14""28""31""4""42""49"
Krunal Nagvadia
16
let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
m.alqadi
quelle
Das Hinzufügen von .lowercased () hat nach einer langen Zeit des Versuchs für mich funktioniert. Ich verstehe nicht warum, da der gesamte Text zunächst in Kleinbuchstaben geschrieben wurde.
Tom Tallak Solbu
Bei Verwendung von Kleinbuchstaben () werden alle Namen in Kleinbuchstaben geändert, um ordnungsgemäß sortiert zu werden :)
m.alqadi
14

Für diejenigen, die Swift 3 verwenden, lautet die entsprechende Methode für die akzeptierte Antwort:

movieArr.sorted { $0.Name < $1.Name }
Jacobo Koenig
quelle
1

Sortiertes Array Swift 4.2

arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })
CSE 1994
quelle
0
*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!
    }*
Muhammad Ahmad
quelle