Dictionaries: Silver Challenge Solutions

Chapter 10 Dictionaries - Pg 112 Silver Challenge

Works, but I’m not sure it’s the most elegant.

Is there a better way to access individual items in each value array and read those into a new array of just the names? How do I get to value [0] in the Chicago Bulls Key more directly? (“Jordan”)

var nbaRoster = ["Chicago Bulls":["Jordan", "Pippen", "Paxon", "Harper", 
                "Grant"],
                "Detroit Pistons":["Thomas","Rodman","Lambeer","Dumars",
                "Aguirre"],
                "Boston Celtics":["Bird","McHale","Parish","Johnson",
                "Ainge"]
]


let nbaPlayers = Array(nbaRoster.values)

var count = 0
var allPlayers: [String] = []

while count < nbaPlayers.count {
    allPlayers += nbaPlayers[count]
    count += 1
}

print("The NBA has the following players: \(allPlayers)")

// The NBA has the following players: ["Jordan", "Pippen", "Paxon", 
"Harper", "Grant", "Bird", "McHale", "Parish", "Johnson", "Ainge", 
"Thomas", "Rodman", "Lambeer", "Dumars", "Aguirre"]

Answering my own question, the elements of the array at each key can be accessed like this:

nbaRoster["Chicago Bulls"]?[0]  //"Jordan"

At first I tried:

nbaRoster["Chicago Bulls"][0]  //no ?

And I got an error:

Value of optional type '[String]?' must be unwrapped to refer to member
'subscript' of wrapped base type '[String]'

So how did this become an optional? My Dictionary nbaRoster is [String:[String]] and not
[String?:[String]].

Can anyone help explain?

Thanks!

This is a safety feature of the language to keep programmers awake at all times :slight_smile:

Indexing a dictionary, or indexing any collection for that matter, returns an optional value to make sure that the programmer handles the case of index values that are not valid for the collection.

In the code above, the dictionary ([String:[String]]) is a collection; so are the stored values ([String]).

2 Likes

To go more directly, I nested two FOR loops, the outer looping through each team key, the next looping through each value array. My team names and players were… uninspired.

// Declare the Dictionary
var league = [
    "TeamA":
        ["Player1", "Player2", "Player3", "Player4", "Player5"],
    "TeamB":
        ["Player6", "Player7", "Player8", "Player9", "Player10"],
    "TeamC":
        ["Player11", "Player12", "Player13", "Player14", "Player15"]
]

// Loop through and display only the players!
var returnString = "The league has the following players: "
for team in league.values {
    for player in team {
        returnString += " \(player)"
    }
}

print(returnString)
1 Like

I need to get more accustom to declaring variable inline (is there a term for it?) in these types of loops.

I always want to use a counter and team++ or team +=1 and forget that’s not necessary.

In general I recommend not being shy about using extra lines and extra variables to make the code more readable. Code is much easier to debug when you can step through it line-by-line to see what changes it’s making. Too many changes to your values on a single line can be difficult to reason with.

2 Likes

This is my solution. Hope that is OK. Sorry for the german expressions.

 var buLiTeams = ["Sportfreunde Borken" : ["Willi", "Gerd", "Robbie"],
                         "TUS Borken" : ["Willy", "Bernd", "Herbert"],
                         "Viktoria Heiden" : ["Hermann", "Aki", "Andreas"]]
for (key, value) in buLiTeams {
  print("\nDer Verein \(key) hat folgende Spieler:\n")
  for player in value {
    print(player)
  }
}

Cheers,
Georg

1 Like

var footballTeam = [
“Zenit”: [“Dzyba”, “Jirkov”, “Kerjakov”, “Ozdoev”, “Malkom”],
“Spartak”: [“Kokorin”, “Bakaev”, “Djikiya”, “Mozes”],
“CSKA”: [“Akinfeev”, “Fernandes”, “Dzagoev”, “Gaich”, “Zainutdinov”]
]

for (key, valueArray) in footballTeam {
print(key + “:”)

valueArray.forEach { (playerName) in
playerName != valueArray.last ? print(playerName) : print(playerName, terminator: “\n\n”)
}

}

Hello,
Here’s my solution to the challange
let footballTeam = [“Man U” : [“Ik”, “Karl”, “Dozie”, “Kachi”],
“Arsenal” : [“Swarez”, “Neymar”, “Messi”, “Pogba”],
“Man City” : [“Scholes”, “Rooney”, “Rashford”, “Benzema”]
]

var message: [String] =
print("The NWSL has the following players: ", terminator: “”)
for (_, value) in footballTeam {
for v in value {
message.append(v)
}
}
print(message)

let Ligue_1 = [
               "PSG" : ["Messi", "Mbappé", "Neymar", "Ramos", "Icardi", "Navas"],
               "Marseille": ["Gerson", "Ünder", "Payet", "Harit", "Milik"],
               "Lille" : ["Yilmaz", "Sanches", "David", "Gomes", "Fonte"]
]

func printPlayers (league: [String:[String]]) {
    var players: [String] = []

    for team in Ligue_1.values {
        players += team
    }
    print("The Ligue 1 has the following players: \(players)")
}

printPlayers(league: Ligue_1)

I found Array’s joined() method to simplify my code:

var sportsTeams = [String:[String]]()
sportsTeams["North Team"] = ["Homer", "Marge", "Bart", "Lisa", "Maggie"]
sportsTeams["South Team"] = ["Kyle", "Cartman", "Kenny", "Stan", "Butters"]
sportsTeams["Old Team"] = ["Luke", "Leia", "Han", "Chewbacca", "R2-D2"]

print("The league has the following players: \(Array(sportsTeams.values.joined()))")    
// The league has the following players: ["Luke", "Leia", "Han", "Chewbacca", "R2-D2", "Kyle", "Cartman", "Kenny", "Stan", "Butters", "Homer", "Marge", "Bart", "Lisa", "Maggie"]