【问题标题】:Sorting a League Table by varying sort options通过不同的排序选项对排行榜进行排序
【发布时间】:2019-04-15 09:05:40
【问题描述】:

我有一个需要排序的 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 }
    }

【问题讨论】:

  • 查看sort(by:)
  • 您可以使用 KeyPath,但您需要从枚举到要排序的属性的 KeyPath 的映射。
  • 在这里查看答案。我认为它可以帮助你stackoverflow.com/questions/43056807/…
  • 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 } }
  • 我刚才用它来按点排序,然后按镜头排序,这可能是最常见的,它工作得很好,但只是一种排列。感谢您的回复,我现在将查看这些内容:)

标签: swift


【解决方案1】:

你可能需要准备这样的东西:

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 以更 Swifty 的方式编写 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"]

【讨论】:

  • 非常感谢您的回复,这看起来像是我一直在尝试但无法做到的。我今天会试试这个:)
  • 这似乎工作得很好,非常感谢您花时间回复。我似乎无法掌握 intProperty 函数提供的枚举和属性之间的联系。大约 2 天前我开始走错路,无法恢复大声笑。几年来,我一直在业余时间学习 swift 和 iOS 开发,这强化了我需要回去学习更多基础知识的事实:)
【解决方案2】:

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

为每个字段(单独!)编写排序算法后,您可以将它们组合起来:

extension LeagueSortOptions {
    func compare(lhs: LeagueTeam, rhs: LeagueTeam) -> ComparisonResult {
        switch self {
            // return comparison result for all LeagueSortOptions
        }
    }
}

// ...
func sort(initialItems: [LeagueTeam], by sortOptions: [LeagueSortOptions]) -> [LeagueTeam]
    var sortedItems = initialItems

    // depending on needs you may want to reverse sortOptions
    for sortOption in sortOptions { 

        // stableSort would call "compare" internally on sortOption
        sortedItems = stableSort(sortOption)
    }
    return sortedItems
}

【讨论】:

  • 非常感谢您的回复,我今天会调查这个:)
猜你喜欢
  • 1970-01-01
  • 2015-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多