通过更改排序选项对联赛表进行排序

时间:2019-04-15 09:05:40

标签: swift

我需要排序一组LeagueTeam。一个联赛团队拥有通常的东西,积分,shotsFor,打击得分,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
}

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

    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 }
    }

2 个答案:

答案 0 :(得分:0)

我认为稳定的排序将是解决方案。 这是@Esqarrouth如何实施的评论:How to stable sort an array in Swift

一旦您为每个字段编写了排序算法(分别!),就可以将它们组合在一起:

dbug

答案 1 :(得分:0)

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

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"]