Silver challenge?


#1

Has anyone completed the silver challenge? when i try to print the result i get this:

South Carolina has the following zipcodes: LazyMapCollection<Dictionary<String, Array<Int>>, Array<Int>>(_base: ["Conway": [29526, 29527, 29528], "Myrtle Beach": [29526, 29527, 29528], "Columbia": [29201, 29202, 29203]], _transform: (Function)

what am i doing Wrong?


#2

Not getting above message anymore but it’s not printing like the result in the book:

var columbiaZip = [29201, 29202, 29203]
var conwayZip = [29526, 29527, 29528]
var myrtleZip = [29526, 29527, 29528]


var southCarolina = ["Columbia": columbiaZip, "Conway": conwayZip , "Myrtle Beach": myrtleZip ]

for zipCodes in southCarolina.values {

print("South Carolina has the following zipcodes: \(zipCodes)")
}

Any ideas?


#3

i was a bit confused here too, but i came up with this:

[code]var Texas = [“Austin”: [12345, 32145, 89320, 23178, 29018],
“Arlen”: [90190, 90210, 18910, 12810, 78210],
“Kickapoo”: [19020, 12123, 12345, 94949, 39202]
]

let zips = Array(Texas.values)

print(“Texas has the following zip codes (zips)”)
[/code]

it outputs:

Texas has the following zip codes [[90190, 90210, 18910, 12810, 78210], [19020, 12123, 12345, 94949, 39202], [12345, 32145, 89320, 23178, 29018]]

i think that covers it?!


#4

If you look at the result in the book he has all the zip codes printed consecutively without the brackets. I can print what you have also, but in the challenge he mentions mapping an array to the dictionary i did some searching but haven’t found a clear answer.


#5

hmm,

i found this method: .flatten()

let zips = Array(Texas.values.flatten())
which changes the output so:

Texas has the following zip codes [90190, 90210, 18910, 12810, 78210, 19020, 12123, 12345, 94949, 39202, 12345, 32145, 89320, 23178, 29018]


#6

Thanks that works better.


#7

[quote=“Squillop”]hmm,

i found this method: .flatten()

let zips = Array(Texas.values.flatten())
which changes the output so:

Texas has the following zip codes [90190, 90210, 18910, 12810, 78210, 19020, 12123, 12345, 94949, 39202, 12345, 32145, 89320, 23178, 29018] [/quote]

It would be helpful if he had mentioned to use the .flatten property. Maybe something for a new edit?

Method nr 2 is another (manual) approach

import Cocoa

var georgiaZip: [String:Array<Int>]

var county1 = [113111, 1212132, 121222]
var county2 = [111321, 1321212, 155212]
var county3 = [115551, 1212112, 121612]


georgiaZip = ["county1": county1, "County2": county2, "County3": county3]

let allZips = Array(georgiaZip.values.flatten()) // Method 1


var flattenedArray = [Int]() // Method 2
for values in georgiaZip.values {
    flattenedArray += values
}

print("Georgia has the following zipcodes: \(allZips)")
print("Georgia has the following zipcodes: \(flattenedArray)")

#8

I came up with the following (using some of what we had already learned):

var floridaDict = Dictionary<String, [Int]>()
floridaDict["Broward"] = [33066, 33065, 33067]
floridaDict["Dade"] = [33139, 33140, 33130]
...

var allZipcodes = [Int]()
for (_, zipCodes) in floridaDict {
    allZipcodes += zipCodes
}

print("Florida has the following zip codes: \(allZipcodes)")

#9

I did something like this:

[code]import Cocoa

var california = [“Amador”: [208, 209], “Calaveras”: [210, 211]]

var zips = Int
for (key, value) in california {
zips += value
}

print(“California has the following zips (zips)”)[/code]

And it gave the expected results


#10

I used nested loops to populate my county arrays (cleverly named one, two and three) of zip codes within the Georgia dictionary.
At first it didn’t work, but thanks to Stack Overflow, I found that you have to force unwrap an array within a dictionary to get append() to work. My code follows:

[code]var one = Int
var two = Int
var three = Int
var georgia = [1: one, 2: two, 3: three]
var zip: Int = 30300

for i in 1…3 {
for j in 1…5 {
zip = zip + 1
georgia[i]!.append(zip)
}
}
print(Array(georgia.values.flatten()))[/code]


#11

Here’s what I came up with:

[code]var texasZips = [“Fort Bend”:[77053, 77406, 77407, 77417, 77441],
“Harris”:[77001, 77002, 77003, 77004, 77005],
“Brazoria”:[77422, 77430, 77431, 77463, 77480]
]

var zips: Array = []

for values in texasZips.values
{
zips += Array(values)
}

print(“Texas has the following zip codes: (zips)”)[/code]

The output of which is:


#12

Thanks for this guys. It wasn’t clear to me how to solve this problem without using a for loop and an additional array variable. I’m concerned that I wasn’t able to find the flatten method in the Array documentation easily. Some of the methods and properties that that the different collection types have aren’t all listed on the page or linked together in a way that is clear.

EDIT: I found where this information is located in the documentation. You have to look at the various Protocols that a Collection has to implement in order to get a full picture of all of the functionality that comes out of the box. Even then it’s still not really clear from what I can tell thus far what all the various collection types can do.


#13

Hi,

The following code is giving the exact required output. But I feel it is very clumsy. Any suggestions to improve this? I appreciate your input.

Thank you.

[code]import Cocoa
var string = “[”

let georgia = [“county1” : [10001, 10002, 10003, 10004, 10005],
“county2” : [20001, 20002, 20003, 20004, 20005],
“county3”: [30001, 30002, 30003, 30004, 30005]
]

let county1 = georgia[“county1”]!
let county2 = georgia[“county2”]!
let county3 = georgia[“county3”]!

let count1 = county1.count
let count2 = county2.count
let count3 = county3.count

for (var i = 0; i < count1; i++)
{
switch i
{
case 0:
string += String(county1[i]) + ","
case count1-1:
string += " " + String(county1[i]) + "\n"
default:
string += " " + String(county1[i]) + “,”
}
}

for (var i = 0; i < count2; i++)
{
if (i != count2-1)
{
string += " " + String(county2[i]) + “,”
}
else
{
string += " " + String(county2[i]) + “\n”
}
}

for (var i = 0; i < count3; i++)
{
if (i != count3-1)
{
string += " " + String(county3[i]) + “,”
}
else
{
string += " " + String(county3[i]) + “]”
}
}

print(string)

[/code]


#14

You could rewrite it like this:

import Cocoa

// -------------------------------------------------------------
//
func print (numbers:Array<Int>, inout to s:String, prefix: String! = nil, suffix: String! = nil)
{
    let count = numbers.count
    guard count > 0 else {
        return
    }
    
    if (prefix != nil) {
        s += prefix
    }
    
    s += String (numbers [0])
    for (var i = 1; i < count; i++)
    {
        s += ", " + String (numbers [i])
    }
    
    if (suffix != nil) {
        s += suffix
    }
}

// -------------------------------------------------------------
//
let georgia = ["county1" : [10001, 10002, 10003, 10004, 10005],
               "county2" : [20001, 20002, 20003, 20004, 20005],
               "county3":  [30001, 30002, 30003, 30004, 30005]
]

let county1 = georgia ["county1"]!
let county2 = georgia ["county2"]!
let county3 = georgia ["county3"]!

// Print all on one line
var string = "["
print (county1, to:&string)

string += ", "
print (county2, to:&string)

string += ", "
print (county3, to:&string)
string += "]"

print (string)

// Print one line per county
string = "["
print (county1, to:&string, suffix:"\n")
print (county2, to:&string, prefix:" ", suffix:"\n")
print (county3, to:&string, prefix:" ")
string += "]"

print (string)

#15

ibex10,

Thank you very much for the response. This looks better.


#16

My approach doesn’t include the formatting of the output to show five zip codes per line, and to right justify them. It’s also a little clunky on the print, because i couldn’t easily remove the trailing comma and remove the space before the right bracket. I like the idea of the flatten and that made it work:

let stateZip = ["Hampden": [11111,22222,33333,44444,55555], "Hampshire": [11122,22233,33344,44455,55566], "Frankilin": [12345,23456,34567,45678,56789]]
let zipCodes = Array(stateZip.values)
print("Massachusetts has the following zip codes: [", terminator: "")
for zipC in zipCodes {
    for indZip in zipC {
        print("\(indZip), ", terminator: "")
    }
}
print("]")

Then if I use flatten it works except for the right justification:

let zipCodes = Array(stateZip.values.flatten())
print("Massachusetts has the following zip codes: \(zipCodes)")

I’m pretty sure the author wants us to figure some of this stuff out on our own, which is good, but makes it frustrating if the answer isn’t obvious.


#17

I live in Massachusetts and our zip codes (along with a number of other states) begin with 0. Therefore using integers won’t work. I used strings. It seems to me that the output in the book is from a single array with 15 values (integers). Here is my solution, with strings, to the Silver Challenge: (if you use integers instead of strings the output is identical to the book’s output.)

let massCountyZipCodeDict = ["Dukes":["02557", "02539", "02568", "02572", "02579"], "Suffolk": ["01234", "01235", "01236","01237", "01238"], "Middlesex": ["02123", "02124", "02125", "02126", "02127"]]

var allMassZipCodes: [String] = []

for (key, value) in massCountyZipCodeDict {
    allMassZipCodes += value
}
print("Massachusetts has the following zip codes \(allMassZipCodes)

Here’s the output:
Massachusetts has the following zip codes [“02123”, “02124”, “02125”, “02126”, “02127”, “02557”, “02539”, “02568”, “02572”, “02579”, “01234”, “01235”, “01236”, “01237”, “01238”]


#18

I realize most people have probably moved onto the 2nd edition of this book using Swift 3, but I am currently studying out of the 1st edition and wanted to post my solution to the Silver Challenge:

var washington = ["King": [98029, 98027, 98004, 98118, 98006],
              "Snohomish": [98203, 98204, 98205, 98206, 98207],
              "Pierce": [98332, 98333, 98335, 98336, 98337]]

var washingtonZipCodes = [Int]()

for (county, zipCodes) in washington {
        for zipCode in zipCodes {
        washingtonZipCodes.append(zipCode)
    }
}

print("Washington has the following zip codes: \(washingtonZipCodes)")

It is essentially nested for-in loops that append to a new array which I print to the console. It’s only a few lines of code which aren’t too verbose. Less code the better. Here is what is printed to the console:

Washington has the following zip codes: [98332, 98333, 98335, 98336, 98337, 98029, 98027, 98004, 98118, 98006, 98203, 98204, 98205, 98206, 98207]


#20

While I like your examples, this one is a lot more elegant and you can even split it up into separate functions to modularize it if you wanted.

    var america = [
    "Minnesota": ["Ramsey County": [55101, 55102, 55103, 55104, 55105],
                  "Dakota County": [55044, 55031, 55076, 55077, 55088],
                  "Hennepin County": [55111, 55305, 55305, 55311, 55313]
                 ]
    
             ]

var answer: Array<Int> = []
// For every State in America
for (state, county) in america
{
    // For every County in the State
    for c in county.values
    {
        // For every Zip Code in county
        for z in c
        {
            
            answer.append(z)
        }
        
    }
}