Swift 地图和过滤器:查找不属于给定玩家的所有工厂
Swift map and filter: Find all factories that are not owned by a given player
我有一个 Swift 游乐场文件,其中有一个工厂列表,其中包含称为引擎的子实体;玩家可以容纳许多引擎的地方
这样的关系;
Factory -> Engine <- Player
- 一个工厂有很多发动机
- 一个玩家有多个引擎
- 一个引擎只有一个父级(工厂)
- 一个引擎只有一个所有者(玩家)
我正在尝试构建一个 Swift 地图和过滤器,它会生成一个列表,其中列出了 不属于 给定玩家对象的所有工厂。
我的代码如下;
//: Swift Playground code
import Foundation
class Factory : CustomStringConvertible {
var name: String = ""
var engines: [Engine] = [Engine]()
var description: String {
return self.name
}
var owners: [Player]? {
let filtered = self.engines.filter { (eng:Engine) -> Bool in
return (eng.owner != nil)
}
.sorted { (engA:Engine, engB:Engine) -> Bool in
return ((engA.owner?.turnOrder)! < (engB.owner?.turnOrder)!)
}.flatMap { (eng:Engine) -> Player? in
return (eng.owner)
}
return filtered
}
init(name: String) {
self.name = name
// create 3 children (engines)
for _ in 1...3 {
let engine = Engine.init(parent: self)
self.engines.append(engine)
}
}
}
class Engine : CustomStringConvertible {
weak var parent: Factory?
weak var owner: Player?
var description: String {
guard let hasParent = self.parent else {
return "N/A"
}
return ("\(hasParent.name) - engine")
}
init(parent: Factory) {
self.parent = parent
}
func setOwner(owner: Player) {
self.owner = owner
self.owner?.addEngine(engine: self)
}
}
class Player : CustomStringConvertible {
var name: String = ""
var engines: [Engine] = [Engine]()
var turnOrder: Int = 0
var description: String {
return self.name
}
init(name: String) {
self.name = name
}
func addEngine(engine: Engine) {
self.engines.append(engine)
}
}
// create 3 factories
let f1 = Factory.init(name: "f1")
let f2 = Factory.init(name: "f2")
let f3 = Factory.init(name: "f3")
let factories = [f1,f2,f3]
let p1 = Player.init(name: "Bob")
if let firstEngine = f1.engines.first {
firstEngine.setOwner(owner: p1)
}
print ("All factories: \(factories)")
print ("p1 = \(p1.name), engines: \(p1.engines)")
for (index, f) in factories.enumerated() {
print ("#\(index), Owners: \(f.owners)")
}
// filter all factories NOT owned by player
let filtered = factories.map({ [=11=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner != nil)
})})
print ("factories not owned by player")
print (filtered)
输出结果如下:
All factories: [f1, f2, f3]
p1 = Bob, engines: [f1 - engine]
#0, Owners: Optional([Bob])
#1, Owners: Optional([])
#2, Owners: Optional([])
factories not owned by player
[[f1 - engine], [], []]
我遇到的问题是最后一个过滤器代码;
// filter all factories NOT owned by player
let filtered = factories.map({ [=13=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner != nil)
})})
这只有 returns 个引擎不为零的工厂,
我想使用:
return (eng.owner != p1)
但是 return 出现错误;
error: cannot convert value of type 'Player' to expected argument type '_OptionalNilComparisonType'
return (eng.owner != p1)
因此我想知道,我怎样才能过滤工厂地图,并且只有 return 给定玩家 不 拥有的所有工厂的列表?
非常感谢
您需要告诉 swift .owner 是什么类型:
let filtered = factories.map({ [=10=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner as? Player != p1)
})})
编辑:可能实际上是'p1'需要设置为播放器,错误消息没有指定。
我想这就是您要找的:
extension Factory {
func isOwned(by player: Player?) -> Bool {
return self.engines.contains(where: { [=10=].isOwned(by: player)} )
}
}
extension Engine {
func isOwned(by player: Player?) -> Bool {
return self.owner === player
}
}
let factoriesNotOwnedByP1 = factories.filter { ![=10=].isOwned(by: p1) }
下面是我要对您的现有代码进行的一些其他更改:
import Foundation
class Factory {
let name: String
var engines = [Engine]()
init(name: String) {
self.name = name
self.engines += (1...3).map{ _ in Engine(parent: self) }
}
var owners: [Player]? {
return self.engines
.lazy
.flatMap { engine in engine.owner.map{ (engine: engine, owner: [=11=]) } }
.sorted { [=11=].owner.turnOrder < .owner.turnOrder }
.map { [=11=].owner }
}
func isOwned(by player: Player?) -> Bool {
return self.engines.contains(where: { [=11=].isOwned(by: player)} )
}
}
extension Factory: CustomStringConvertible {
var description: String { return self.name }
}
class Engine {
weak var parent: Factory?
weak var owner: Player?
init(parent: Factory) {
self.parent = parent
}
func setOwner(owner: Player) {
self.owner = owner
self.owner?.addEngine(engine: self)
}
}
extension Engine: CustomStringConvertible {
var description: String {
guard let parent = self.parent else { return "N/A" }
return ("\(parent.name) - engine")
}
}
class Player {
let name: String
var engines = [Engine]()
var turnOrder = 0
init(name: String) {
self.name = name
}
func addEngine(engine: Engine) {
self.engines.append(engine)
}
}
extension Player: CustomStringConvertible {
var description: String { return self.name }
}
let factories = [
Factory(name: "f1"),
Factory(name: "f2"),
Factory(name: "f3"),
]
let p1 = Player(name: "Bob")
factories.first?.engines.first?.setOwner(owner: p1)
print ("All factories: \(factories)")
print ("p1 = \(p1.name), engines: \(p1.engines)")
for (index, f) in factories.enumerated() {
print("#\(index), Owners: \(String(describing: f.owners))")
}
let factoriesNotOwnedByP1 = factories.filter { ![=11=].isOwned(by: p1) }
print("factories not owned by player: ")
print(factoriesNotOwnedByP1)
我有一个 Swift 游乐场文件,其中有一个工厂列表,其中包含称为引擎的子实体;玩家可以容纳许多引擎的地方
这样的关系;
Factory -> Engine <- Player
- 一个工厂有很多发动机
- 一个玩家有多个引擎
- 一个引擎只有一个父级(工厂)
- 一个引擎只有一个所有者(玩家)
我正在尝试构建一个 Swift 地图和过滤器,它会生成一个列表,其中列出了 不属于 给定玩家对象的所有工厂。
我的代码如下;
//: Swift Playground code
import Foundation
class Factory : CustomStringConvertible {
var name: String = ""
var engines: [Engine] = [Engine]()
var description: String {
return self.name
}
var owners: [Player]? {
let filtered = self.engines.filter { (eng:Engine) -> Bool in
return (eng.owner != nil)
}
.sorted { (engA:Engine, engB:Engine) -> Bool in
return ((engA.owner?.turnOrder)! < (engB.owner?.turnOrder)!)
}.flatMap { (eng:Engine) -> Player? in
return (eng.owner)
}
return filtered
}
init(name: String) {
self.name = name
// create 3 children (engines)
for _ in 1...3 {
let engine = Engine.init(parent: self)
self.engines.append(engine)
}
}
}
class Engine : CustomStringConvertible {
weak var parent: Factory?
weak var owner: Player?
var description: String {
guard let hasParent = self.parent else {
return "N/A"
}
return ("\(hasParent.name) - engine")
}
init(parent: Factory) {
self.parent = parent
}
func setOwner(owner: Player) {
self.owner = owner
self.owner?.addEngine(engine: self)
}
}
class Player : CustomStringConvertible {
var name: String = ""
var engines: [Engine] = [Engine]()
var turnOrder: Int = 0
var description: String {
return self.name
}
init(name: String) {
self.name = name
}
func addEngine(engine: Engine) {
self.engines.append(engine)
}
}
// create 3 factories
let f1 = Factory.init(name: "f1")
let f2 = Factory.init(name: "f2")
let f3 = Factory.init(name: "f3")
let factories = [f1,f2,f3]
let p1 = Player.init(name: "Bob")
if let firstEngine = f1.engines.first {
firstEngine.setOwner(owner: p1)
}
print ("All factories: \(factories)")
print ("p1 = \(p1.name), engines: \(p1.engines)")
for (index, f) in factories.enumerated() {
print ("#\(index), Owners: \(f.owners)")
}
// filter all factories NOT owned by player
let filtered = factories.map({ [=11=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner != nil)
})})
print ("factories not owned by player")
print (filtered)
输出结果如下:
All factories: [f1, f2, f3]
p1 = Bob, engines: [f1 - engine]
#0, Owners: Optional([Bob])
#1, Owners: Optional([])
#2, Owners: Optional([])
factories not owned by player
[[f1 - engine], [], []]
我遇到的问题是最后一个过滤器代码;
// filter all factories NOT owned by player
let filtered = factories.map({ [=13=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner != nil)
})})
这只有 returns 个引擎不为零的工厂,
我想使用:
return (eng.owner != p1)
但是 return 出现错误;
error: cannot convert value of type 'Player' to expected argument type '_OptionalNilComparisonType'
return (eng.owner != p1)
因此我想知道,我怎样才能过滤工厂地图,并且只有 return 给定玩家 不 拥有的所有工厂的列表?
非常感谢
您需要告诉 swift .owner 是什么类型:
let filtered = factories.map({ [=10=].engines.filter({ (eng: Engine) -> Bool in
return (eng.owner as? Player != p1)
})})
编辑:可能实际上是'p1'需要设置为播放器,错误消息没有指定。
我想这就是您要找的:
extension Factory {
func isOwned(by player: Player?) -> Bool {
return self.engines.contains(where: { [=10=].isOwned(by: player)} )
}
}
extension Engine {
func isOwned(by player: Player?) -> Bool {
return self.owner === player
}
}
let factoriesNotOwnedByP1 = factories.filter { ![=10=].isOwned(by: p1) }
下面是我要对您的现有代码进行的一些其他更改:
import Foundation
class Factory {
let name: String
var engines = [Engine]()
init(name: String) {
self.name = name
self.engines += (1...3).map{ _ in Engine(parent: self) }
}
var owners: [Player]? {
return self.engines
.lazy
.flatMap { engine in engine.owner.map{ (engine: engine, owner: [=11=]) } }
.sorted { [=11=].owner.turnOrder < .owner.turnOrder }
.map { [=11=].owner }
}
func isOwned(by player: Player?) -> Bool {
return self.engines.contains(where: { [=11=].isOwned(by: player)} )
}
}
extension Factory: CustomStringConvertible {
var description: String { return self.name }
}
class Engine {
weak var parent: Factory?
weak var owner: Player?
init(parent: Factory) {
self.parent = parent
}
func setOwner(owner: Player) {
self.owner = owner
self.owner?.addEngine(engine: self)
}
}
extension Engine: CustomStringConvertible {
var description: String {
guard let parent = self.parent else { return "N/A" }
return ("\(parent.name) - engine")
}
}
class Player {
let name: String
var engines = [Engine]()
var turnOrder = 0
init(name: String) {
self.name = name
}
func addEngine(engine: Engine) {
self.engines.append(engine)
}
}
extension Player: CustomStringConvertible {
var description: String { return self.name }
}
let factories = [
Factory(name: "f1"),
Factory(name: "f2"),
Factory(name: "f3"),
]
let p1 = Player(name: "Bob")
factories.first?.engines.first?.setOwner(owner: p1)
print ("All factories: \(factories)")
print ("p1 = \(p1.name), engines: \(p1.engines)")
for (index, f) in factories.enumerated() {
print("#\(index), Owners: \(String(describing: f.owners))")
}
let factoriesNotOwnedByP1 = factories.filter { ![=11=].isOwned(by: p1) }
print("factories not owned by player: ")
print(factoriesNotOwnedByP1)