Swift: ordena la matriz de objetos alfabéticamente


138

Tengo esto:

class Movies {
  Name:String
  Date:Int
}

y una gran variedad de [Películas]. ¿Cómo clasifico la matriz alfabéticamente por nombre? He intentado:

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

y

movieArr = sorted(movieArr)

pero eso no funciona porque no estoy accediendo al atributo de nombre de Películas.

Respuestas:


297

En el cierre al que pasa sort, compare las propiedades por las que desea ordenar. Me gusta esto:

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

o lo siguiente en los casos que desea omitir:

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

Nota al margen: por lo general, solo los tipos comienzan con una letra mayúscula; Recomiendo usar namey date, no Namey Date.


Ejemplo, en un patio de recreo:

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 estará en el orden [movieA, movieB, movieC]

Actualización Swift5

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

Gracias, recién estoy comenzando con Swift, y no sabía sobre el uso de cierres.
cdpalmer

1
use movies.sort en lugar de movies.sorted @Mike S
Oskariagon el

1
gracias por la explicación. Mejoré mi edición, debería estar bien, por favor, eche un vistazo :)
Julian Król

8
Cuidado, esto no funcionará al ordenar cadenas que pueden o no estar en mayúsculas. La comparación de .lowercaseStringresolverá este problema.
Matthieu Riegler

2
@EricAya Tenga en cuenta que está sorteden Swift 3 nuevamente: D.
dvp.petrov

45

Con Swift 3, puede elegir una de las siguientes formas de resolver su problema.


1. Usar sorted(by:​)con una Movieclase que no se ajusta al Comparableprotocolo

Si su Movieclase no se ajusta al Comparableprotocolo, debe especificar en su cierre la propiedad en la que desea utilizar el sorted(by:​)método Array .

Movie declaración de clase:

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. Usar sorted(by:​)con una Movieclase que se ajuste al Comparableprotocolo

Sin embargo, al hacer que su Movieclase se ajuste al Comparableprotocolo, puede tener un código mucho conciso cuando desee utilizar el sorted(by:​)método de Array .

Movie declaración de clase:

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. Usar sorted()con una Movieclase que se ajuste al Comparableprotocolo

Al hacer que su Movieclase se ajuste al Comparableprotocolo, puede usar el sorted()método de Array como alternativa a sorted(by:​).

Movie declaración de clase:

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

Oye, ¿hay alguna diferencia? entre 2do y 3ro (excepto movies.sorted(by: <)y movies.sorted())?
Kamaldeep singh Bhatia

sorted(by:)y sorted()son dos métodos diferentes. Puede usar array.sorted()como alternativa para array.sorted(by: <).
Imanou Petit

Sí, solo preguntando en caso de definición de clase, ¿necesitamos cambiar algo? Quiero decir, ¿podemos tener la misma definición de clase para ambos sorted(by:)y sorted()?
Kamaldeep singh Bhatia

1
Sí, puede tener la misma implementación de su clase / estructura que, en cualquier caso, debe ajustarse al Comparableprotocolo.
Imanou Petit

Tengo Array con customObject cuando juego en orden ascendente no se está acortando de la manera adecuada. "1" "14""28""31""4""42""49"
Krunal Nagvadia

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

agregar .lowercased () funcionó para mí después de un largo período de prueba. No entiendo por qué, ya que todo el texto estaba en minúscula para empezar.
Tom Tallak Solbu

cuando el uso de minúsculas () va a cambiar todos los nombres en minúsculas a ordenados correctamente :)
m.alqadi

14

Para aquellos que usan Swift 3, el método equivalente para la respuesta aceptada es:

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

1

Matriz ordenada 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!
    }*
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.