Swift 使用条件排名数组进行归约和求和
Swift reduce and sum with condition ranking array
我想数一数胜利的次数并对所有分数求和。
我想使用 flatmap map and reduce 来降低复杂度。为了确保我可以用 for cycles
获得它
问题是,在 allMatch 中,我可以有不同的 teamID(团队可以单人或多人比赛)并且顺序无关紧要(例如 teamID 1,2 等于 teamID 2, 1
struct InfoMatch: Hashable {
let teamId: Set<Int>
let rank: Int
let mPoints: Int
let vPoints: Int
}
所有比赛都是数组的数组,因为它returns每场比赛的每支球队的信息,在这个例子中,第一场比赛有 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{[=12=].filter{[=12=].rank == 1}}
let losers = allMatch.map{[=12=].filter{[=12=].rank != 1}}
print(winners)
打印:
[[__lldb_expr_7.InfoMatch(teamId: Set([1, 2]), rank: 1, mPoints: 200,
vPoints: 0)], [__lldb_expr_7.InfoMatch(teamId: Set([3, 4]), rank: 1,
mPoints: 0, vPoints: 20)], [__lldb_expr_7.InfoMatch(teamId: Set([1,
2]), rank: 1, mPoints: 40, vPoints: 0)]]
我想要一个 returns
的数组
teamID: victoryCount: loserCount: mPoints: vPoints:
对于那个例子:
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
我真的很想知道使用flatmap map和reduce是否可以降低复杂度,但是你可以在这个中使用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{[=11=]}.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)
我想数一数胜利的次数并对所有分数求和。
我想使用 flatmap map and reduce 来降低复杂度。为了确保我可以用 for cycles
获得它问题是,在 allMatch 中,我可以有不同的 teamID(团队可以单人或多人比赛)并且顺序无关紧要(例如 teamID 1,2 等于 teamID 2, 1
struct InfoMatch: Hashable {
let teamId: Set<Int>
let rank: Int
let mPoints: Int
let vPoints: Int
}
所有比赛都是数组的数组,因为它returns每场比赛的每支球队的信息,在这个例子中,第一场比赛有 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{[=12=].filter{[=12=].rank == 1}}
let losers = allMatch.map{[=12=].filter{[=12=].rank != 1}}
print(winners)
打印:
[[__lldb_expr_7.InfoMatch(teamId: Set([1, 2]), rank: 1, mPoints: 200, vPoints: 0)], [__lldb_expr_7.InfoMatch(teamId: Set([3, 4]), rank: 1, mPoints: 0, vPoints: 20)], [__lldb_expr_7.InfoMatch(teamId: Set([1, 2]), rank: 1, mPoints: 40, vPoints: 0)]]
我想要一个 returns
的数组teamID: victoryCount: loserCount: mPoints: vPoints:
对于那个例子:
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
我真的很想知道使用flatmap map和reduce是否可以降低复杂度,但是你可以在这个中使用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{[=11=]}.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)