Swift: Mengurutkan larik objek menurut abjad

145

Aku punya ini:

class Movies {
  Name:String
  Date:Int
}

dan serangkaian [Film]. Bagaimana cara mengurutkan array menurut abjad? Saya sudah mencoba:

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

dan

movieArr = sorted(movieArr)

tapi itu tidak berhasil karena saya tidak mengakses atribut nama Film.

Jonah Ruffer
sumber

Jawaban:

309

Di closure yang Anda teruskan sort, bandingkan properti yang ingin Anda sortir. Seperti ini:

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

atau berikut ini jika Anda ingin mengabaikan kasus:

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

Catatan sisi: Biasanya hanya jenis yang dimulai dengan huruf besar; Saya akan merekomendasikan penggunaan namedan date, bukan Namedan Date.


Contoh, di taman bermain:

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 akan diurutkan [movieA, movieB, movieC]

Pembaruan Swift5

channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
            let channelName1 = channel1.name
            let channelName2 = channel2.name
            return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)
Mike S.
sumber
Terima kasih, saya baru memulai dengan Swift, dan saya tidak tahu tentang penggunaan closure.
cdpalmer
1
menggunakan movies.sort daripada movies.sorted @Mike S
Oskariagon
1
terima kasih atas penjelasannya. Meningkatkan hasil edit saya, semestinya baik-baik saja, silakan lihat :)
Julian Król
9
Hati-hati, ini tidak akan berfungsi saat mengurutkan string yang mungkin atau mungkin tidak menggunakan huruf besar. Membandingkan keinginan .lowercaseStringakan memecahkan masalah ini.
Matthieu Riegler
2
@EricAya Note ada sorteddi Swift 3 lagi: D.
dvp.petrov
47

Dengan Swift 3, Anda dapat memilih salah satu cara berikut untuk menyelesaikan masalah Anda.


1. Menggunakan sorted(by:​)dengan Moviekelas yang tidak sesuai dengan Comparableprotokol

Jika Moviekelas Anda tidak sesuai dengan Comparableprotokol, Anda harus menentukan dalam closure Anda properti yang ingin Anda gunakan sorted(by:​)metode Array .

Movie deklarasi kelas:

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
    }

}

Pemakaian:

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. Menggunakan sorted(by:​)dengan Moviekelas yang sesuai dengan Comparableprotokol

Namun, dengan membuat Moviekelas Anda sesuai dengan Comparableprotokol, Anda dapat memiliki kode yang lebih ringkas saat Anda ingin menggunakan sorted(by:​)metode Array .

Movie deklarasi kelas:

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
    }

}

Pemakaian:

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. Menggunakan sorted()dengan Moviekelas yang sesuai dengan Comparableprotokol

Dengan membuat Moviekelas Anda sesuai dengan Comparableprotokol, Anda dapat menggunakan sorted()metode Array sebagai alternatif sorted(by:​).

Movie deklarasi kelas:

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
    }

}

Pemakaian:

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
sumber
Hei, apakah ada perbedaan. antara ke-2 dan ke-3 (kecuali movies.sorted(by: <)dan movies.sorted())?
Kamaldeep singh Bhatia
sorted(by:)dan sorted()dua metode berbeda. Anda dapat menggunakan array.sorted()sebagai alternatif array.sorted(by: <).
Imanou Petit
Ya, hanya dengan bertanya dalam kasus definisi kelas apakah kita perlu mengubah sesuatu? Maksud saya, dapatkah kita memiliki definisi kelas yang sama untuk keduanya sorted(by:)dan sorted()?
Kamaldeep singh Bhatia
1
Ya, Anda dapat memiliki implementasi yang sama dari kelas / struct Anda yang, bagaimanapun, harus sesuai dengan Comparableprotokol.
Imanou Petit
Saya memiliki Array dengan customObject ketika saya shoer dalam urutan naik itu tidak korslet dengan cara yang benar. "1" "14""28""31""4""42""49"
Krunal Nagvadia
17
let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })
m.alqadi
sumber
menambahkan .lowercased () berhasil untuk saya setelah lama mencoba. Saya tidak mengerti mengapa, karena semua teks awalnya menggunakan huruf kecil.
Tom Tallak Solbu
ketika menggunakan huruf kecil () akan mengubah semua nama menjadi huruf kecil untuk diurutkan dengan benar :)
m.alqadi
14

Bagi mereka yang menggunakan Swift 3, metode yang setara untuk jawaban yang diterima adalah:

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

Array yang diurutkan Swift 4.2

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

Sebagian besar jawaban ini salah karena kegagalan menggunakan perbandingan berbasis lokal untuk pengurutan. Lihat localizedStandardCompare ()

Eric
sumber