James Goldstein James Goldstein - 5 months ago 17
Swift Question

Swift: for loop, search dictionary, set variables from keys

Error is: Cannot convert value of type (String: Int)? to specified type 'String'.

Obviously my dictionary 'roster' is 'String: Int' and the local variables ('lastPlayer' and 'firstPlayer') inside function 'printRoster' is String. But I've tried every variation with no luck. It worked fine before I made roster a dictionary, and it was just a String.

What it should do: function concatenates a string so that it has correct punctuation. First string is "The roster includes", then we add on each player located in the Key of the dictionary 'roster'. But the first key in the roster gets no comma and the last key gets an ', and'.

Also, can I add the dictionary 'roster' to the protocol, didn't see the syntax in any of the Apple manuals

import UIKit

protocol basketballTeams {
var teamName: String? { get }
var numberOfPlayers: Int? { get }
var locatedIn: String? { get }

func printTeamLocation()
}

class BasketballTeam {
var teamName: String?
var numberOfPlayers: Int?
var locatedIn: String?
var roster = [String: Int]()

init(teamName: String) {
self.teamName = teamName
}

func printTeamLocation() -> String {
return "The \(teamName) are located in \(locatedIn)"
}
func printRoster() -> String {
var rosterPrint = "The roster includes"
for player in roster.keys {

rosterPrint += player

var firstPlayer: String = roster.first
var lastPlayer = roster.last

if (player == firstPlayer) {
rosterPrint += " \(player)"
}
else if (player == lastPlayer) {
rosterPrint += ", and \(player)."
}
else {
rosterPrint += ", \(player)"
}
}
return rosterPrint
}
}

enum NumberedPosition: Int {
case PointGuard = 1
case ShootingGuard, SmallForward, PowerForward, Center
func labelOfPosition() -> String {
switch self {
case .PointGuard:
return "Point Guard"
case .ShootingGuard:
return "Shooting Guard"
case .SmallForward:
return "Small Forward"
case .PowerForward:
return "Power Forward"
case .Center:
return "Center"
default:
"Position doesn't exit"
}
}
}

let goldenStateWarriors = BasketballTeam(teamName: "Golden State Warriors")
goldenStateWarriors.numberOfPlayers = 12
goldenStateWarriors.locatedIn = "Oakland, California"
goldenStateWarriors.roster = ["Stephen Curry" : 1, "Andrew Bogut" : 5, "Klay Thompson" : 2]
goldenStateWarriors.roster["Harrison Barnes"] = 3

Answer

If you still want to add the "and" to the last row you can use this function:

func printRoster() -> String {
  var rosterPrint = "The roster includes"
  let arr = Array(roster.keys)
  let firstPlayer: String = arr.first!
  let lastPlayer: String = arr.last!
  for (player, _ ) in roster {
    switch player {
    case firstPlayer:
      rosterPrint += " \(player)"
    case lastPlayer:
      rosterPrint += ", and \(player)."
    default:
      rosterPrint += ", \(player)"
    }
   }
   return rosterPrint
}

and call it like so:

print(goldenStateWarriors.printRoster())