Swift: сортировка массива объектов по алфавиту

У меня есть это:

class Movies {
  Name:String
  Date:Int
}

и массив из [Фильмы]. Как отсортировать массив по алфавиту по имени? Я пробовал:

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

и

movieArr = sorted(movieArr)

но это не работает, потому что я не получаю доступ к атрибуту name для фильмов.

Ответ 1

В замыкании, которое вы передаете sort, сравните свойства, по которым вы хотите отсортировать. Как это:

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

или следующие случаи, которые вы хотите обойти,

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

Sidenote: Обычно только шрифты начинаются с заглавной буквы; Я бы рекомендовал использовать name и date, а не Name и Date.


Пример на детской площадке:

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 будет в порядке [movieA, movieB, movieC]

Ответ 2

С Swift 3 вы можете выбрать один из следующих способов решения вашей проблемы.


1. Использование sorted(by:​) Movie классом Movie, который не соответствует Comparable протоколу

Если ваш класс Movie не соответствует протоколу Comparable, вы должны указать в закрытии свойство, для которого вы хотите использовать метод Array sorted(by:​) :).

Объявление класса Movie:

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
    }

}

Использование:

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. Использование sorted(by:​) Movie классом Movie, соответствующим Comparable протоколу

Однако, Movie класс Movie соответствие с протоколом Comparable, вы можете получить очень лаконичный код, если хотите использовать метод Array sorted(by:​) :).

Объявление класса Movie:

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
    }

}

Использование:

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. Использование sorted() с классом Movie, соответствующим протоколу Comparable

Movie класс Movie соответствие с протоколом Comparable, вы можете использовать метод Array sorted() в качестве альтернативы sorted(by:​).

Объявление класса Movie:

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
    }

}

Использование:

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

Ответ 3

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

Ответ 4

Для тех, кто использует Swift 3, эквивалентный метод для принятого ответа:

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

Ответ 5

Swift 4 == Они немного изменили синтаксис со времен Swift 3. Вот строка версии ** Swift 4 **. Дел >

Ответ 6

Сортированный массив Swift 4.2

arrayOfRaces = arrayOfItems.sorted(by: { ($0["raceName"] as! String) < ($1["raceName"] as! String) })