654 Stimmen

Wie man ein Array von benutzerdefinierten Objekten nach dem Wert einer Eigenschaft in Swift sortiert

Sagen wir, wir haben eine benutzerdefinierte Klasse namens imageFile und diese Klasse enthält zwei Eigenschaften:

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

Viele von ihnen sind in einem Array gespeichert:

var images : Array = []

var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)

aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)

Wie kann ich das Bilderarray nach 'fileID' in aufsteigender oder absteigender Reihenfolge sortieren?

14voto

McKinley Punkte 364

Wenn die Array-Elemente Comparable entsprechen, können Sie einfach die funktionale Syntax verwenden:

array.sort(by: <)

Wenn Sie basierend auf einem benutzerdefinierten Typ sortieren, müssen Sie lediglich den <-Operator implementieren:

class ImageFile {
    let fileName: String
    let fileID: Int
    let fileSize: Int
    static func < (left: ImageFile, right: ImageFile) -> Bool {
        return left.fileID < right.fileID
    }
}

Manchmal möchten Sie jedoch nicht nur eine Standardmethode zum Vergleichen von ImageFiles haben. Möglicherweise möchten Sie in bestimmten Kontexten Bilder basierend auf fileID sortieren und anderswo basierend auf fileSize. Für dynamische Vergleiche haben Sie zwei Optionen.

sorted(by:)

images = images.sorted(by: { a, b in
    // True zurückgeben, wenn `a` vor `b` im sortierten Array steht
    if a.fileID < b.fileID { return true }
    if a.fileID > b.fileID { return false }
    // Krawatten durch Vergleich von Dateigrößen brechen
    return a.fileSize > b.fileSize
})

Sie können die Syntax vereinfachen, indem Sie eine Abschlussklammer verwenden:

images.sorted { ... }

Das manuelle Tippen von if-Anweisungen kann jedoch zu langem Code führen (wenn wir Dateigrößenknoten brechen möchten, indem wir basierend auf Dateinamen sortieren, würden wir eine ziemlich lange if-Verkettung haben). Diese Syntax können wir durch Verwendung des brandneuen SortComparator-Protokolls (macOS 12+, iOS 15+) vermeiden:

sorted(using:)

files = files.sorted(using: [
    KeyPathComparator(\.fileID, order: .forward),
    KeyPathComparator(\.fileSize, order: .reverse),
])

Dieser Code sortiert die Dateien basierend auf ihrer Datei-ID (.forward bedeutet aufsteigend) und bricht Knoten, indem er basierend auf der Dateigröße sortiert (.reverse bedeutet absteigend). Die Syntax \.fileID ist, wie wir Schlüsselpfade spezifizieren. Sie können die Liste der Vergleicher beliebig erweitern.

11voto

Vicky Prajapati Punkte 137

Sie können ein sortiertes Array aus der fileID-Eigenschaft auf folgende Weise zurückgeben:

Swift 2

let sortedArray = images.sorted({ $0.fileID > $1.fileID })

Swift 3 ODER 4

let sortedArray = images.sorted(by: { $0.fileID > $1.fileID })

Swift 5.0

let sortedArray = images.sorted {
    $0.fileID < $1.fileID
}

9voto

kwerle Punkte 1748

Wenn Sie dieses Array an mehr als einer Stelle sortieren werden, kann es sinnvoll sein, Ihren Array-Typ Comparable zu machen.

class MyImageType: Comparable, Printable {
    var fileID: Int

    // Für Printable
    var description: String {
        get {
            return "ID: \(fileID)"
        }
    }

    init(fileID: Int) {
        self.fileID = fileID
    }
}

// Für Comparable
func <(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID < right.fileID
}

// Für Comparable
func ==(left: MyImageType, right: MyImageType) -> Bool {
    return left.fileID == right.fileID
}

let one = MyImageType(fileID: 1)
let two = MyImageType(fileID: 2)
let twoA = MyImageType(fileID: 2)
let three = MyImageType(fileID: 3)

let a1 = [one, three, two]

// gibt ein sortiertes Array zurück
println(sorted(a1)) // "[ID: 1, ID: 2, ID: 3]"

var a2 = [two, one, twoA, three]

// sortiert das Array 'vor Ort'
sort(&a2)
println(a2) // "[ID: 1, ID: 2, ID: 2, ID: 3]"

7voto

dorian Punkte 847

Wenn Sie keine benutzerdefinierten Objekte verwenden, sondern Werttypen, die das Comparable-Protokoll implementieren (Int, String usw.), können Sie dies einfach tun:

myArray.sort(>) // absteigende Reihenfolge sortieren

Ein Beispiel:

struct MyStruct: Comparable {
    var name = "Unbenannt"
}

func <(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name < rhs.name
}
// Implementierung von == erforderlich durch Equatable
func ==(lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()

value2.name = "Ein neuer Name"

var anArray:[MyStruct] = []
anArray.append(value1)
anArray.append(value2)

anArray.sort(>) // Dies wird das Array in absteigender Reihenfolge sortieren

6voto

Priyank Patel Punkte 713

Swift 3,4,5

    struct imageFile  {
        var fileName = String()
        var fileID = Int()
    }

    //Objekte hinzufügen wie folgt
    var arrImages = [imageFile]()
    arrImages.append(.init(fileName: "Hallo1.png", fileID: 1))
    arrImages.append(.init(fileName: "Hallo3.png", fileID: 3))
    arrImages.append(.init(fileName: "Hallo2.png",fileID: 2))

    //Array-Sortierung mit folgendem Code
    let sortImagesArr = arrImages.sorted(by: {$0.fileID < $1.fileID})
    print(sortImagesArr)

    //Ausgabe

    imageFile(fileName: "Hallo1.png", fileID: 1),
    imageFile(fileName: "Hallo2.png", fileID: 2),
    imageFile(fileName: "Hallo3.png", fileID: 3)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X