Silver challenge: Dictionaries


#12

I recognize this doesn’t exactly match the instructions given for the exercise, but in the interest of trying to get to the end using the least amount of code necessary, I solved the problem thusly. Wasn’t able to figure out how to incorporate a where clause, however, to limit the output to just MD.

var BaltimoreCity = [21221, 21222, 21223, 21224, 21225]
var BaltimoreCounty = [21101, 21102, 21103, 21104, 21105]
var Washington = [20001, 20002, 20003, 20004, 20005]

var zips = ["Maryland": [BaltimoreCity, BaltimoreCounty], "DistrictOfColumbia": Washington] as [String : Any]

for (state, zip) in zips {
    print("The State of \(state) has the following zip codes:  \(zip)")
}

Output:

The State of DistrictOfColumbia has the following zip codes:  [20001, 20002, 20003, 20004, 20005]
The State of Maryland has the following zip codes:  [[21221, 21222, 21223, 21224, 21225], [21101, 21102, 21103, 21104, 21105]]

#13

// Silver challenge
// NornIron = Northern Ireland, BTW :slight_smile:


var dicNornIron: [String:Array<String>]
dicNornIron = ["Down":["BT20", "BT19", "BT18", "BT17", "BT16"], "Antrim":["AN1", "AN2", "AN3", "AN4", "AN5"], "Fermanagh":["EN10", "EN11", "EN12", "EN13", "EN14"]]

var arrPostcodes: [String] = []
for postcode in dicNornIron.values {
    arrPostcodes += postcode
}
print ("Norn Iron has the following postcodes: \(arrPostcodes)")

// Bit extra, just for practice
for (county, postcodes) in dicNornIron {
    print ("County \(county) has the following postcodes: \(postcodes)")
}

Gives:

Norn Iron has the following postcodes: [“BT20”, “BT19”, “BT18”, “BT17”, “BT16”, “AN1”, “AN2”, “AN3”, “AN4”, “AN5”, “EN10”, “EN11”, “EN12”, “EN13”, “EN14”]
County Down has the following postcodes: [“BT20”, “BT19”, “BT18”, “BT17”, “BT16”]
County Antrim has the following postcodes: [“AN1”, “AN2”, “AN3”, “AN4”, “AN5”]
County Fermanagh has the following postcodes: [“EN10”, “EN11”, “EN12”, “EN13”, “EN14”]


#14

Tom, you need to define michiganZipCodes as a string if you defined the zip codes as a string:

var michiganZipCodes: [String] = []

I did, so your solution screwed me a bit up. Otherwise, very nice!


#15

//Silver Challenge - I was able to cut out some code by calling Array(nyCounty.values.joined())

var nyCounty = [
“Onondaga”: [13135, 13138, 13141, 13152, 13153],
“Jefferson”: [13601, 13602, 13603, 13605, 13606],
“Onieda”: [13054, 13123, 13157, 13162, 13301]
]

var zipcodes = Array(nyCounty.values.joined())
print(“NY has the following zip codes: (zipcodes)”) //(zipcodes) should have the “” preceding it

Which prints out “NY has the following zip codes: [13601, 13602, 13603, 13605, 13606, 13054, 13123, 13157, 13162, 13301, 13135, 13138, 13141, 13152, 13153]”


#16

My silver & gold challenge answers. I put a lot of comments on my gold challenge so you can see why I did what I did. All the comments make it look a lot longer than it is.

I used a switch statement for the gold challenge and created a variable to hold the number of white spaces needed to properly indent, depended on how many white spaces are in the intro. This way the indents will line up even if we change the intro.

//silver challenge
let countiesIllinois = ["A County" : [11111, 22222, 33333, 44444, 55555],
                        "B County" : [11101, 22202, 33303, 44404, 55505],
                        "C County" : [11110, 22220, 33330, 44440, 55550]
]
var allZipCodes: [Int] = []

for countyZips in countiesIllinois.values {
    for eachZip in countyZips {
        allZipCodes.append(eachZip)
    }
}

print("Illinois has these zip codes: \(allZipCodes)")

//add below for gold challenge

let intro = "Zip Codes in Illinois: "
print(intro, terminator:"") //print the intro and stay on the same line
var numOfWhiteSpaces = intro.characters.count // this is an Int variable that holds the count for the number of characters in our intro- "Zip codes in Illinois: "- that's 23 characters. Now we can let the compiler know to put 23 white spaced before every new line of zip codes. That will keep every line of zip codes lined up with the first line
var iterationsWhiteSpace = 1 //used to count iterations for the while loop below
var stringWhiteSpace = "" //This will be our string of white spaces. We will add 23 white spaces to this string using the while loop below and the two variables above

while iterationsWhiteSpace <= numOfWhiteSpaces {
    stringWhiteSpace += " "
    iterationsWhiteSpace += 1
}

var iteration = 1 //used for the switch/for-in loop below
let lastZipCode = allZipCodes.count //use the count property to get the place of the last zipcode. We will use this in the nested switch in the for-in loop below.

for zip in allZipCodes {
    switch iteration {   
    case 1: //if it's the 1st zip add a bracket, print, comma, and don't return to the next line.
        print("[\(zip),", terminator:" ")
        stringWhiteSpace += " " // add one more white space to account for the bracket we added
    case lastZipCode: //if it's the last zip print, add an end bracket, no comma, and return.
        print("\(zip)]")
    case let thisIteration where thisIteration % 5 != 0: // if it's not a fifth zip, print and don't return
        print("\(zip),", terminator:" ")
    default:// if it is a fifth zip in line, print, return, and add white space
            print("\(zip),")
            print(stringWhiteSpace, terminator:"")
    }
    iteration += 1 //add an iteration
}

#17

My solutions:

// silver challenge
let california = ["Hassoun County": [10001, 10002, 10003, 10004, 10005],
                  "Bilbo County": [20001, 20002, 20003, 20004, 20005],
                  "Hiho County": [30100, 30102, 30103, 30104, 30105]]

var zipCodes: [Int] = []
for codes in california.values {
    zipCodes += codes
}

print("California has the following zipcodes: \(zipCodes)")

// gold challenge
print("California has the following zipcodes: [", terminator: "")
for code in zipCodes[0...4] {
    print("\(code), ", terminator: "")
}
print("\n\t\t\t\t\t\t\t\t\t\t", terminator: "")
for code in zipCodes[5...9] {
    print("\(code), ", terminator: "")
}
print("\n\t\t\t\t\t\t\t\t\t\t", terminator: "")
for code in zipCodes[10...13] {
    print("\(code), ", terminator: "")
}
print("\(zipCodes[14])]")

#18

My gold solution:

var states: [String:Array<Int>] = [:]
states["AA"] = [10000, 11000, 12000, 13000, 10000, 15000, 16000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000]
states["BBBBBBBB"] = [50000, 60000, 70000, 80000, 90000, 51000, 52000, 53000, 54000, 55000, 56000, 57000]
states["CCCCCCCCCCCCC"] = [90000, 65000, 50000, 63000, 70000, 80000]
states["DDDDD"] = [90000, 65000, 50000]

for (key, value) in states {
    let stateString = "\(key) has the following zip codes: ["
    print(stateString, terminator: "")
    for i in 1...value.count {
        if i == value.count {
            print("\(value[i-1])]")
        } else if i % 5 == 0 {
            print("\(value[i-1]), ")
            for i in 1...stateString.characters.count {
                print(" ", terminator: "")
            }
        } else {
            print("\(value[i-1]), ", terminator: "")
        }
    }
}

#19

I believe this is the first challenge where the book recommends looking at the Apple documentation.

It suggests searching the documentation for the print() function.

In xcode, if you go to the menu Help -> Documentation and API Reference, you will get a search field. Here is what happens for the following entries in that search field:

"print"
many entries appear but nothing related to the print function of Swift

“print()” as suggested in the book
many entries appear but nothing related to the print function of Swift

"print("
many entries appear including one labeled “print(_:separator:terminator)” about halfway down. This is actually what you want, but as a novice Apple developer, this was not obvious to me.

Here is my suggestion:

  • in Xcode go to the menu Help -> Documentation and API Reference
  • enter “Array” in the search box
  • scroll to the top of the page and you will see
  • Swift Standard Library > Array
  • click on Swift Standard Library (which is a hyperlink)
  • you are now at the root of the Swift Standard Library in the Apple documentation
  • create a bookmark to this location

From this page, you will see a link to “print(_:separator:terminator:)” and if you follow it, it will describe the Swift print statement.


#20

Here’s my silver and gold answers. The gold answer is not elegant, I just built up a string and then printed it.

let douglasCounty = [“80134”, “80203”, “80138”, “80001”, “80002”]
let arapahoeCounty = [“80234”, “80126”, “81780”, “80003”, “80004”]
let adamsCounty = [“89075”, “83401”, “87210”, “80006”, “80007”]
var coloradoCounties = [“Douglas County”: douglasCounty,
“Arapahoe County”: arapahoeCounty,
“Adams County”: adamsCounty]

var numArray: [Int] = []
for strings in coloradoCounties.values {
for zipcode in strings {
if let num = Int(zipcode) {
numArray.append(num)
}
}
}

var printStr = "Colorado has the following zip codes: ["
let whiteSpaceCount = printStr.characters.count
printStr += "(numArray[0]), " + "(numArray[1]),\n"
for i in 2…4 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 1…whiteSpaceCount {
printStr += " "
}
for i in 5…6 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 7…9 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 1…whiteSpaceCount {
printStr += " "
}

for i in 10…11 {
printStr += "(numArray[i]), "
}
printStr += "\n"
for i in 12…13 {
printStr += "(numArray[i]), "
}
printStr += "(numArray[14])"
print(printStr)


#21

// Silver Challenge

var Nevada = [“Clark County”: [1, 2, 3], “Bear County”: [4, 5, 6], “Shark County”: [7, 8, 9]]

for (county, zips) in Nevada {
print("(county) has the following zip codes: (zips)")


#22

For the gold challenge, I tried to eliminate any hardcoded values in the code so it would automatically work with any number of counties. I also didn’t want to have any extra loop counters, just have it automatically detect the various ending points.

var stateZipcodes = ["Calhoun":  ["12345", "23456", "34567", "45678", "56789"],
                     "Fayette":  ["12346", "23457", "34568", "45679", "56780"],
                     "Houghton": ["54321", "65432", "76543", "87654", "98765"]]
var output = "Georgia has the following zip codes: ["
let spaces = String(repeating: " ", count: output.characters.count)
print(output, terminator:"")

let countyArray = Array(stateZipcodes.keys)
for county in countyArray
{
    let countyZipcodes = stateZipcodes[county] ?? []
    for zipcode in countyZipcodes
    {
        print(zipcode, terminator:"")
        if (zipcode != countyZipcodes.last)
        {
            print(", ", terminator:"") // still more zip codes on this line
        }
        else if county != countyArray.last
        {
            print(",")                   // last zip code on this line but not the last line, so use normal line termination
            print(spaces, terminator:"") //  and indent the next line
        }
        else
        {
            print("]") // last zip code in last county, so we're done
        }
    }
}

The only potential issue with this code is that if a county has more or less than 5 zip codes, you won’t get 5 zip codes printed on each line. To fix that you’d have to count the number of zip codes printed and start a new line after every fifth one, not just after each county.


#23

The first solution in this thread is way more elegant than mine. But, this is what I came up with for the Silver Challenge.

//Silver Challenge
//Create arrays of zips
var polkZip = [30306, 30307, 30308, 30309, 30310]
var booneZip = [30311, 30312, 30313, 30314, 30315]
var marshallZip = [30301, 30302, 30303, 30304, 30305]

//Create a dictionary of counties that maps to the zip arrays
var counties = ["Polk": polkZip, "Boone": booneZip, "Marshall": marshallZip]

//Create an array to hold all zips in the dictionary
var zipHolder = [0]

//This is the weird bit.  I have to initialize the array with something and then remove it from the array. If I try to append to the array when it is empty I get errors.
zipHolder.remove(at: 0)

// loop through them to pull out the values for each county
for zips in counties.values {
    // Get a count of the number of zips in the given array
    var countyZipCount = zips.count
    
    //Set a counter so that we can iterate through each array and put the values in each array into the zipHolder array
    var counter = 0
    while counter < countyZipCount {
        zipHolder.append(zips[counter])
        counter += 1
    }
}
// Print out the long list of Zips
print("Iowa has the following zip codes: \(zipHolder)")

I would appreciate any advice on initializing the array before using it. It seems I MUST put a value in the array before appending new values to it. However, if I give the array an initial value and then remove it, all is fine. Hmmmmmm


#24

Read page 82: If you just declare an Array and then try to append you get an error.
The solution is to create an empty array: var zipHolder = [Int] (). Then U don’t need to remove anything. With empty array you do 2 things declare and initialize.


#25

//Silver Challenge
Update Here’s my new solution working as expected. In as few lines as possible.

import Cocoa

var georgia = [“Cobb” : [30064, 30193, 38263, 30060, 34920] , “Fulton” : [37283, 30312, 38943, 30314, 36647 ] , “Gwinnett” : [30028, 36462, 32938, 32389, 31119] ]

var resultArray : [Int] = []
for zipCodes in georgia.values
{
for zip in zipCodes
{
resultArray.append(zip)
}
}
print(“Georgia has the following zip codes :” , resultArray)

//Georgia has the following zip codes : [37283, 30312, 38943, 30314, … ]


#26

Similar solution here:

var ctZips = ["Fairfield": [06464,06614,06615, 06515, 06516],
              "New Haven": [10001, 10111, 10101, 10005, 11003],
              "Litchfield": [07711, 07001, 05523, 08899, 02020]]

var bigZipList = Array<Int>()
for zip in ctZips.values {
    bigZipList += zip
}

print("CT has the following zip codes: \(bigZipList)")

#27

Maybe mine is weird…
import Cocoa
var china = [“hubei”:[101,102,103,104,105],
“shanghai”:[201,201,203,204,205],
“zhejinag”:[301,302,303,304,305],
“hunan”:[401,402,403,404,405]];
let post = Dictionary<String,Double>();
for post in china{
print(post);
}


#28

If you post your code between a pair of 3 back tick marks (```), you will make it easier to read:

var postCodes = [
    "hubei"   : [101,102,103,104,105],
    "shanghai": [201,201,203,204,205],
    "zhejinag": [301,302,303,304,305],
    "hunan"   : [401,402,403,404,405]];

// pretty print...
var maxKeyLen = 0
for (key, _) in postCodes {
    if maxKeyLen < key.count {
        maxKeyLen = key.count
    }
}

for (key, value) in postCodes {
    let padding = String (repeating: " ", count: maxKeyLen - key.count)
    print ("\(key) \(padding): \(value)");
}

should output:

hunan    : [401, 402, 403, 404, 405]
shanghai : [201, 201, 203, 204, 205]
zhejinag : [301, 302, 303, 304, 305]
hubei    : [101, 102, 103, 104, 105]

Become a Competent Programmer


#29

thank you ,I think I have mastered these contents,Thank you very much your reply.

Maybe we can make a friend, My name is 张威,My hometown is in China。

I’m sorry to reply you so late。

we can now send messages by email at any time


#30

Here goes my code:

//Silver Chapter.10
let zipCodesA = [94541, 94542, 94543, 94544, 94545]
let zipCodesB = [94551, 94552, 94553, 94554, 94555]
let zipCodesC = [94561, 94562, 94563, 94564, 94565]
let california = ["Alameda": zipCodesA, "Contra Costa": zipCodesB, "San Francisco": zipCodesC]
        var zipContainer = [Int]()

        for i in zipCodesA {
            zipContainer.append(i)
        }
        for i in zipCodesB {
            zipContainer.append(i)
        }
        for i in zipCodesC {
            zipContainer.append(i)
        }
        print("California has the following zip codes: \(zipContainer)")


//Silver: mo'betta, refactored for/in loop
        for i in california.values {
            for zip in i {
                zipContainer.append(zip)
            }
        }
        print("California has the following zip codes: \(zipContainer)"

#31

Most understandable code solution to the gold challenge that I’ve found yet. Nice work.:+1:t3: