Быстрое уменьшение и суммирование с массивом ранжирования по условиям - PullRequest
0 голосов
/ 15 июня 2019

Я бы хотел посчитать количество побед и сложить все очки.

Я позволю себе использовать карту карты и уменьшить ее, чтобы уменьшить сложность. Конечно, я могу получить его за циклы

Проблема в том, что в allMatch у меня может быть другой teamID (команда может играть в одиночку или пару человек) и не имеет значения порядок (например, teamID 1,2 равен teamID 2,1

struct InfoMatch: Hashable {
    let teamId: Set<Int>
    let rank: Int
    let mPoints: Int
    let vPoints: Int
}

Все совпадения - это массив массивов, поскольку он возвращает информацию о каждой команде для каждого матча, в этом примере первый матч проводится с 2 командами, а последний - с 3 командами

let allMatch: [[InfoMatch]] = [
    [InfoMatch(teamId:[1,2],rank:1,mPoints: 200,vPoints: 0),InfoMatch(teamId:[3,4],rank:2,mPoints: 100,vPoints: 0)],
    [InfoMatch(teamId:[1,2],rank:2,mPoints: 0,vPoints: 10),InfoMatch(teamId:[4,3],rank:1,mPoints: 0,vPoints: 20)],
    [InfoMatch(teamId:[2,1],rank:1,mPoints: 40,vPoints: 0),InfoMatch(teamId:[3,4],rank:2,mPoints: 30,vPoints: 0),InfoMatch(teamId:[5,6],rank:3,mPoints: 5,vPoints: 0)]
]
let winners = allMatch.map{$0.filter{$0.rank == 1}}
let losers = allMatch.map{$0.filter{$0.rank != 1}}

print(winners)

печать:

[[__lldb_expr_7.InfoMatch (teamId: Set ([1, 2]), ранг: 1, mPoints: 200, vPoints: 0)], [__lldb_expr_7.InfoMatch (teamId: Set ([3, 4]), ранг: 1, mPoints: 0, vPoints: 20)], [__lldb_expr_7.InfoMatch (teamId: Set ([1, 2]), ранг: 1, mPoints: 40, vPoints: 0)]]

Я бы хотел массив, который возвращает

teamID: victoryCount: loserCount: mPoints: vPoints:

для этого примера:

teamID: 1,2 victoryCount: 2 loserCount: 1 mPoints: 240 vPoints: 10 teamID: 3,4 victoryCount: 1 проигравшийCount: 2 mПунктов: 130 vПунктов: 20 teamID: 5,6 victoryCount: 0 loserCount: 1 mPoints: 5 vPoints: 0

1 Ответ

0 голосов
/ 15 июня 2019

Мне действительно интересно, если использовать карту карты и уменьшить , можно уменьшить сложность , но вы можете использовать reduce таким образом.

Сначала вы говорите, что хотите teamID: victoryCount: loserCount: mPoints: vPoints: , затем вам лучше определить тип для его представления:

struct MatchStats {
    var teamID: Set<Int>
    var victoryCount: Int
    var loserCount: Int
    var mPoints: Int
    var vPoints: Int
}

//For convenience...
extension MatchStats {
    init(teamID: Set<Int>) {
        self.teamID = teamID
        victoryCount = 0
        loserCount = 0
        mPoints = 0
        vPoints = 0
    }
}

//For debugging...
extension MatchStats: CustomStringConvertible {
    public var description: String {
        let teamIDStr = teamID.sorted().map(String.init).joined(separator: ",")
        return "teamID:\(teamIDStr) victoryCount:\(victoryCount) loserCount:\(loserCount) mPoints:\(mPoints) vPoints:\(vPoints)"

    }
}

И используйте его следующим образом в reduce с flatMap:

let teamStats: [Set<Int>: MatchStats] = allMatch.flatMap{$0}.reduce(into: [:]) {result, info in
    result[info.teamId, default: MatchStats(teamID: info.teamId)].victoryCount += info.rank == 1 ? 1 : 0
    result[info.teamId]!.loserCount += info.rank == 1 ? 0 : 1
    result[info.teamId]!.mPoints += info.mPoints
    result[info.teamId]!.vPoints += info.vPoints
}

print(teamStats.values)

Выход:

[teamID:1,2 victoryCount:2 loserCount:1 mPoints:240 vPoints:10, teamID:3,4 victoryCount:1 loserCount:2 mPoints:130 vPoints:20, teamID:5,6 victoryCount:0 loserCount:1 mPoints:5 vPoints:0]

(Вывод может быть в произвольном порядке при каждом вызове. Но сортировка - это другая проблема.)


Как вы думаете, использование reduce намного лучше, чем это?

var teamStats: [Set<Int>: MatchStats] = [:]
for match in allMatch {
    for info in match {
        teamStats[info.teamId, default: MatchStats(teamID: info.teamId)].victoryCount += info.rank == 1 ? 1 : 0
        teamStats[info.teamId]!.loserCount += info.rank == 1 ? 0 : 1
        teamStats[info.teamId]!.mPoints += info.mPoints
        teamStats[info.teamId]!.vPoints += info.vPoints
    }
}

print(teamStats.values)
...