swift - 通过不同的排序选项对排行榜进行排序

标签 swift

我有一个 LeagueTeam 数组需要排序。联盟球队有常用的东西,points、shotsFor、shotsAgainst、totalShots 等。联盟将有一系列 LeagueSortOptions,例如 [.points, .shots, .shotsFor]。这将按分数排序,然后按总投篮次数排序,然后按投篮次数排序。

leagueSortOptions 由用户在创建联赛时创建,因此可以根据用户的需求采用任何顺序,例如。

[.points, .shots, .shotsFor]
[.shots, .shotsFor]
[.shotsFor, .points]

我可能需要添加更多排序选项,所以我觉得需要某种递归,而不是为每个可能的排列创建一个函数。但我就是无法理解它,已经绕了好几个小时了。任何帮助或正确方向的指示将不胜感激,谢谢:)

enum LeagueSortOptions: String, Codable {
      case points = "Points", shots = "Shots", shotsFor = "Shots For"
}


struct LeagueTeam : Codable {
    var name: String
    var gamesPlayed: Int
    var gamesWon: Int
    var gamesLost: Int
    var gamesDrawn: Int
    var shots: Int
    var points: Int

    var shotsFor: Int
    var shotsAgainst: Int
}

我目前使用此代码按点排序,然后按 shotFor 排序,但这仅考虑一种排列,这可能是最常见的:

    teams.sort { (team1, team2) -> Bool in
        if team1.points == team2.points {
            if team1.shots > team2.shots { return true } else { return false }
        }
        if team1.points > team2.points { return true } else { return false }
    }

最佳答案

您可能需要准备如下内容:

extension LeagueTeam {
    func compare(to other: LeagueTeam, by sortOptions: [LeagueSortOptions]) -> ComparisonResult {
        for option in sortOptions {
            let num1 = self.intProperty(for: option)
            let num2 = other.intProperty(for: option)
            if num1 < num2 {
                return .orderedAscending
            } else if num1 > num2 {
                return .orderedDescending
            }
        }
        return .orderedSame
    }

    func intProperty(for sortOption: LeagueSortOptions) -> Int {
        switch sortOption {
        case .points:
            return self.points
        case .shots:
            return self.shots
        case .shotsFor:
            return self.shotsFor
        //`LeagueSortOptions` would have more cases?
        //...
        }
    }
}

(您也许可以使用 KeyPath 以更快速的方式编写 intProperty(for:),但这是另一个问题。)

您可以将数组排序为:

var teams: [LeagueTeam] = [
    LeagueTeam(name: "a", gamesPlayed: 0, gamesWon: 0, gamesLost: 0, gamesDrawn: 0, shots: 0, points: 100, shotsFor: 10, shotsAgainst: 20),
    LeagueTeam(name: "b", gamesPlayed: 0, gamesWon: 0, gamesLost: 0, gamesDrawn: 0, shots: 0, points: 100, shotsFor: 20, shotsAgainst: 10),
    LeagueTeam(name: "c", gamesPlayed: 0, gamesWon: 0, gamesLost: 0, gamesDrawn: 0, shots: 0, points: 110, shotsFor: 120, shotsAgainst: 100),
]
var sortOptions: [LeagueSortOptions] = [.points, .shots, .shotsFor]

teams.sort {(team1, team2) -> Bool in
    return team1.compare(to: team2, by: sortOptions) == .orderedDescending
}
print(teams.map{$0.name}) //->["c", "b", "a"]

关于swift - 通过不同的排序选项对排行榜进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55685814/

相关文章:

ios - 不同类型的 Json 属性

ios - 如何在 swift 2 中正确地将 viewController 锁定在特定方向?

swift - 添加 UIButton 目标时为 "classname has no member functionname"

ios - 用户通知 : Custom Vibration pattern

swift - 二元运算符 '>=' 不能应用于类型 ' (UnsafePointer<Int8>,Int32) -> UnsafeMutablePointer<Int8>' 和 'Int' 的操作数

swift - 在 swift 中创建一个 16 字节的零数组

json - 以编程方式创建按钮

ios - swift 3.0 错误 : Escaping closures can only capture inout parameters explicitly by value

ios - UIStepper不会注册任何事件

ios - 如何将 bgra8Unorm iOS-Metal 纹理转换为 rgba8Unorm 纹理?