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.

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)

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]
 */

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() })

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 }

1

Sortiertes Array Swift 4.2

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

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!
    }*
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.