假设我们有一个名为imageFile的自定义类,这个类包含两个属性:

class imageFile  {
    var fileName = String()
    var fileID = Int()
}

很多都存储在一个数组中:

var images : Array = []

var aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 101
images.append(aImage)

aImage = imageFile()
aImage.fileName = "image1.png"
aImage.fileID = 202
images.append(aImage)

我如何排序的图像数组由'fileID'升序或降序?


当前回答

在Swift 3.0中

images.sort(by: { (first: imageFile, second: imageFile) -> Bool in
    first. fileID < second. fileID
})

其他回答

使用KeyPath排序

你可以像这样通过KeyPath排序:

myArray.sorted(by: \.fileName, <) /* using `<` for ascending sorting */

通过实现这个有用的扩展。

extension Collection{
    func sorted<Value: Comparable>(
        by keyPath: KeyPath<Element, Value>,
        _ comparator: (_ lhs: Value, _ rhs: Value) -> Bool) -> [Element] {
        sorted { comparator($0[keyPath: keyPath], $1[keyPath: keyPath]) }
    }
}

希望Swift在不久的将来把这个添加到语言的核心中。

如果数组元素符合Comparable,那么你可以简单地使用函数语法:

array.sort(by: <)

如果你是基于自定义类型排序,你所需要做的就是实现<运算符:

class ImageFile {
    let fileName: String
    let fileID: Int
    let fileSize: Int
    static func < (left: ImageFile, right: ImageFile) -> Bool {
        return left.fileID < right.fileID
    }
}

但是,有时您不需要一种标准的比较imagefile的方法。也许在某些上下文中,您希望基于fileID对图像进行排序,而在其他地方,您希望基于fileSize对图像进行排序。对于动态比较,您有两个选项。

(by: sorted)

images = images.sorted(by: { a, b in
    // Return true if `a` belongs before `b` in the sorted array
    if a.fileID < b.fileID { return true }
    if a.fileID > b.fileID { return false }
    // Break ties by comparing file sizes
    return a.fileSize > b.fileSize
})

你可以使用尾随闭包来简化语法:

images.sorted { ... }

但是手动输入if语句会导致代码很长(如果我们想通过基于文件名排序来打破文件大小的束缚,我们将会有一个相当长的if厄运链)。我们可以通过使用全新的SortComparator协议(macOS 12+, iOS 15+)来避免这种语法:

排序(使用:)

files = files.sorted(using: [
    KeyPathComparator(\.fileID, order: .forward),
    KeyPathComparator(\.fileSize, order: .reverse),
])

这段代码根据文件ID()对文件进行排序。Forward表示升序),并根据文件大小(。反向意味着下降)。\。fileID语法是我们指定关键路径的方式。您可以根据需要扩展比较器列表。

在Swift 5中,Array有两个方法,分别是sorted()和sorted(by:)。第一个方法sorted()有如下声明:

返回排序后的集合元素。

func sorted() -> [Element]

第二个方法,排序(通过:),有如下声明:

返回集合的元素,使用给定的谓词作为元素之间的比较进行排序。

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

# 1。对可比较的对象进行升序排序

如果集合中的元素类型符合Comparable协议,则可以使用sorted()以升序对元素进行排序。下面的Playground代码展示了如何使用sorted():

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

    static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID < rhs.fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted()
print(sortedImages)

/*
 prints: [ImageFile with ID: 100, ImageFile with ID: 200, ImageFile with ID: 300]
 */

# 2。对可比较的对象按降序排序

如果集合中的元素类型符合Comparable协议,则必须使用sorted(by:)以降序对元素进行排序。

class ImageFile: CustomStringConvertible, Comparable {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

    static func ==(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID == rhs.fileID
    }

    static func <(lhs: ImageFile, rhs: ImageFile) -> Bool {
        return lhs.fileID < rhs.fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0 > img1
})
//let sortedImages = images.sorted(by: >) // also works
//let sortedImages = images.sorted { $0 > $1 } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

# 3。对不可比较的对象按升序或降序排序

如果集合中的元素类型不符合Comparable协议,则必须使用sorted(by:)以升序或降序对元素进行排序。

class ImageFile: CustomStringConvertible {

    let fileName: String
    let fileID: Int
    var description: String { return "ImageFile with ID: \(fileID)" }

    init(fileName: String, fileID: Int) {
        self.fileName = fileName
        self.fileID = fileID
    }

}

let images = [
    ImageFile(fileName: "Car", fileID: 300),
    ImageFile(fileName: "Boat", fileID: 100),
    ImageFile(fileName: "Plane", fileID: 200)
]

let sortedImages = images.sorted(by: { (img0: ImageFile, img1: ImageFile) -> Bool in
    return img0.fileID < img1.fileID
})
//let sortedImages = images.sorted { $0.fileID < $1.fileID } // also works
print(sortedImages)

/*
 prints: [ImageFile with ID: 300, ImageFile with ID: 200, ImageFile with ID: 100]
 */

注意,Swift还提供了两个方法sort()和sort(by:)作为sorted()和sorted(by:)的对应,如果你需要对你的集合进行就地排序。

斯威夫特3、4、5所示

    struct imageFile  {
        var fileName = String()
        var fileID = Int()
    }
    
    //append objects like this
    var arrImages = [imageFile]()
    arrImages.append(.init(fileName: "Hello1.png", fileID: 1))
    arrImages.append(.init(fileName: "Hello3.png", fileID: 3))
    arrImages.append(.init(fileName: "Hello2.png",fileID: 2))

    
    //array sorting using below code
    let sortImagesArr = arrImages.sorted(by: {$0.fileID < $1.fileID})
    print(sortImagesArr)
    
    //output
    
    imageFile(fileName: "Hello1.png", fileID: 1),
    imageFile(fileName: "Hello2.png", fileID: 2),
    imageFile(fileName: "Hello3.png", fileID: 3)
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

students.sort(by: >)

print(students)

彼得Prints:“[””、“科菲Kweku”、“”、“Akosua Abena”、“]”