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.