arrays - Swift map and filter: Find all factories that are not owned by a given player -


i have swift playground file have list of factories child entities called engines; player can hold many engines

the relationship thus;

factory -> engine <- player

  • one factory has many engines
  • one player has many engines
  • one engine has single parent (factory)
  • one engine has single owner (player)

i'm trying build swift map , filter where, produces list of factories not owned given player object.

my code follows;

//: 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)         _ 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)")  (index, f) in factories.enumerated() {     print ("#\(index), owners: \(f.owners)") }  // filter factories not owned player  let filtered = factories.map({ $0.engines.filter({ (eng: engine) -> bool in         return (eng.owner != nil)     })})  print ("factories not owned player")  print (filtered) 

the output follows:

all factories: [f1, f2, f3] p1 = bob, engines: [f1 - engine] #0, owners: optional([bob]) #1, owners: optional([]) #2, owners: optional([]) factories not owned player [[f1 - engine], [], []] 

the issue i'm having last filter code;

// filter factories not owned player  let filtered = factories.map({ $0.engines.filter({ (eng: engine) -> bool in         return (eng.owner != nil)     })}) 

this returns factories engines not nil,

i wish use:

return (eng.owner != p1)

but error returned;

error: cannot convert value of type 'player' expected argument type '_optionalnilcomparisontype'         return (eng.owner != p1) 

i'm wondering, how can filter map of factories , return list of factories given player not own?

many thanks

i think you're looking for:

extension factory {     func isowned(by player: player?) -> bool {         return self.engines.contains(where: { $0.isowned(by: player)} )     } }  extension engine {     func isowned(by player: player?) -> bool {         return self.owner === player     } }  let factoriesnotownedbyp1 = factories.filter { !$0.isowned(by: p1) } 

and here other changes make existing code:

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: $0) } }             .sorted { $0.owner.turnorder < $1.owner.turnorder }             .map { $0.owner }     }      func isowned(by player: player?) -> bool {         return self.engines.contains(where: { $0.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)")  (index, f) in factories.enumerated() {     print("#\(index), owners: \(string(describing: f.owners))") }   let factoriesnotownedbyp1 = factories.filter { !$0.isowned(by: p1) }  print("factories not owned player: ") print(factoriesnotownedbyp1) 

Comments

Popular posts from this blog

javascript - Create a stacked percentage column -

Optimising Firebase database by automatically overwriting data -

javascript - Angular UI-Grid customTemplate directive causing rows to load slowly/? -