Swift: ordina la matrice di oggetti in ordine alfabetico


138

Ho questo:

class Movies {
  Name:String
  Date:Int
}

e una serie di [Film]. Come posso ordinare l'array in ordine alfabetico per nome? Ho provato:

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

e

movieArr = sorted(movieArr)

ma non funziona perché non accedo all'attributo name di Movies.

Risposte:


297

Nella chiusura a cui passi sort, confronta le proprietà che desideri ordinare. Come questo:

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

o quanto segue nei casi in cui si desidera ignorare i casi:

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

Sidenote: in genere solo i tipi iniziano con una lettera maiuscola; Consiglierei di usare namee date, non Namee Date.


Esempio, in un parco giochi:

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 sarà nell'ordine [movieA, movieB, movieC]

Aggiornamento Swift5

channelsArray = channelsArray.sorted { (channel1, channel2) -> Bool in
            let channelName1 = channel1.name
            let channelName2 = channel2.name
            return (channelName1.localizedCaseInsensitiveCompare(channelName2) == .orderedAscending)

Grazie, sto iniziando con Swift e non sapevo dell'uso delle chiusure.
— cdpalmer,

1
usa movies.sort invece di movies.sorted @Mike S
— Oskariagon

1
grazie per la spiegazione. Migliorata la mia modifica, dovrebbe andare bene, per favore dai un'occhiata :)
— Julian Król

8
Attenzione, questo non funzionerà quando si ordina una stringa che può essere o meno maiuscola. Il confronto .lowercaseStringrisolverà questo problema.
— Matthieu Riegler,

2
@EricAya Nota che è sorteddi nuovo in Swift 3: D.
— dvp.petrov,

45

Con Swift 3, puoi scegliere uno dei seguenti modi per risolvere il tuo problema.


1. Utilizzo sorted(by:​)con una Movieclasse non conforme al Comparableprotocollo

Se la Movieclasse non è conforme al Comparableprotocollo, è necessario specificare nella chiusura la proprietà su cui si desidera utilizzare il sorted(by:​)metodo Array .

Movie dichiarazione di classe:

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
    }

}

Uso:

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. Utilizzo sorted(by:​)con una Movieclasse conforme al Comparableprotocollo

Tuttavia, rendendo la Movieclasse conforme al Comparableprotocollo, è possibile avere un codice molto conciso quando si desidera utilizzare il sorted(by:​)metodo Array .

Movie dichiarazione di classe:

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
    }

}

Uso:

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. Utilizzo sorted()con una Movieclasse conforme al Comparableprotocollo

Rendendo la tua Movieclasse conforme al Comparableprotocollo, puoi utilizzare il sorted()metodo Array in alternativa a sorted(by:​).

Movie dichiarazione di classe:

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
    }

}

Uso:

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

Ehi, c'è qualche differenza. tra il 2o e il 3o (tranne movies.sorted(by: <)e movies.sorted())?
— Kamaldeep Singh Bhatia,

sorted(by:)e sorted()sono due metodi diversi. È possibile utilizzare array.sorted()come alternativa per array.sorted(by: <).
— Imanou Petit,

Sì, solo chiedendo in caso di definizione della classe dobbiamo cambiare qualcosa? Voglio dire, possiamo avere la stessa definizione di classe per entrambi sorted(by:)e sorted()?
— Kamaldeep singh Bhatia,

1
Sì, puoi avere la stessa implementazione della tua classe / struttura che, in ogni caso, deve essere conforme al Comparableprotocollo.
— Imanou Petit,

Ho un array con customObject quando sparo in ordine crescente non sta cortocircuitando in modo corretto. "1" "14""28""31""4""42""49"
— Krunal Nagvadia,

16
let sortArray =  array.sorted(by: { $0.name.lowercased() < $1.name.lowercased() })

aggiungendo .lowercased () ha funzionato per me dopo un lungo periodo di tentativi. Non capisco perché, dato che tutto il testo è stato minuscolo per cominciare.
— Tom Tallak Solbu il

quando usi le lettere minuscole () cambieranno tutti i nomi in lettere minuscole per
— ordinarle

14

Per coloro che utilizzano Swift 3, il metodo equivalente per la risposta accettata è:

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

1

Matrice ordinata 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!
    }*
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.