在 Swift 中按属性对类或结构数组进行排序的通用函数

avr*_*rit 4 arrays sorting generics swift

我想创建一个通用函数来根据传递的属性对类数组进行排序。

例如,我有这些课程

public class Car {
    var id: Int
    var manufacturer: String
    var variant: String

    init(id: Int, manufacturer: String, variant: String) {
        self.id = id
        self.manufacturer = manufacturer
        self.variant = variant
    }
}

enum Gender {
    case male
    case female
}

public class Person {
    var id: Int
    var name: String
    var age: Int
    var gender: Gender

    init(id: Int, name: String, age: Int, gender: Gender) {
        self.id = id
        self.name = name
        self.age = age
        self.gender = gender
    }
}
Run Code Online (Sandbox Code Playgroud)

而这些数组,

let cars = [
    Car(id: 1, manufacturer: "Ford", variant: "Focus"),
    Car(id: 2, manufacturer: "Nissan", variant: "Skyline"),
    Car(id: 3, manufacturer: "Dodge", variant: "Charger"),
    Car(id: 4, manufacturer: "Chevrolet", variant: "Camaro"),
    Car(id: 5, manufacturer: "Ford", variant: "Shelby")
]

let persons = [
    Person(id: 1, name: "Ed Sheeran", age: 26, gender: .male),
    Person(id: 2, name: "Phil Collins", age: 66, gender: .male),
    Person(id: 3, name: "Shakira", age: 40, gender: .female),
    Person(id: 4, name: "Rihanna", age: 25, gender: .female),
    Person(id: 5, name: "Bono", age: 57, gender: .male)
]
Run Code Online (Sandbox Code Playgroud)

如何为数组编写通用扩展,根据传递的属性对其进行排序?(例如persons.sort(name) 或cars.sort(manufacturer))

谢谢!

Swe*_*per 5

干得好:

extension Array {
    mutating func propertySort<T: Comparable>(_ property: (Element) -> T) {
        sort(by: { property($0) < property($1) })
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

persons.propertySort({$0.name})
Run Code Online (Sandbox Code Playgroud)

这是一个非变异版本:

func propertySorted<T: Comparable>(_ property: (Element) -> T) -> [Element] {
    return sorted(by: {property($0) < property($1)})
}
Run Code Online (Sandbox Code Playgroud)

正如 Leo Dabus 指出的那样,您可以将扩展推广到任何MutableCollection也是RandomAccessCollection

extension MutableCollection where Self : RandomAccessCollection {
    ...
Run Code Online (Sandbox Code Playgroud)