Swift:按字母顺序对对象数组进行排序


137

我有这个:

class Movies {
  Name:String
  Date:Int
}

和[电影]数组。如何按名称的字母顺序对数组进行排序?我试过了:

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

movieArr = sorted(movieArr)

但这不起作用,因为我没有访问电影的名称属性。

Answers:


297

在传递给的闭包中sort,比较要排序的属性。像这样:

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

或以下要绕过案例的案例:

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

旁注:通常,只有类型以大写字母开头;我建议使用nameand date,而不是Nameand 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]

Swift5更新

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

谢谢,我只是从Swift开始,我不知道闭包的使用。
cdpalmer

1
使用movies.sort代替movies.sorted @Mike S
Oskariagon

1
感谢您的解释。改进了我的编辑,应该没问题,请看一下:)
朱利安·克罗(JulianKról)2015年

8
当心,当排序可能会或可能不会大写的字符串时,这将不起作用。比较.lowercaseString将解决此问题。
Matthieu Riegler

2
@EricAya注意sorted再次在Swift 3中:D。
dvp.petrov '16

44

使用Swift 3,您可以选择以下方法之一来解决问题。


1. sorted(by:​)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符合Comparable协议的类一起使用

但是,通过使您的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类符合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]
 */

嘿,有什么区别吗?在第二和第三之间(movies.sorted(by: <)和除外movies.sorted())?
卡马尔迪普·辛格·巴蒂亚

sorted(by:)sorted()是两种不同的方法。您可以array.sorted()用作的替代方法array.sorted(by: <)
Imanou Petit

是的,只是在类定义的情况下问我们是否需要更改任何内容?我的意思是,我们可以为sorted(by:)和定义相同的类sorted()吗?
卡马尔迪普·辛格·巴蒂亚

1
是的,您可以在任何情况下都必须遵循Comparable协议的类/结构具有相同的实现。
Imanou Petit

当我按升序穿鞋时,我有带有customObject的数组,它没有以正确的方式短路。 "1" "14""28""31""4""42""49"
Krunal Nagvadia

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

经过长时间的尝试,添加.lowercased()对我有用。我不明白为什么,因为所有文本一开始都是小写的。
汤姆·塔拉克·索布

当使用lowercased()时,会将所有名称更改为小写以正确排序:)
m.alqadi 18/12/18


1

排序数组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!
    }*
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.