· 9 years ago · Jun 12, 2017, 10:28 AM
1// Functional Programming exercises.
2//
3// Rules:
4// 1. No loops (for, while, do/while)!
5// 2. No if, else, or switch statements.
6// 3. No "var" variables - only "let".
7//
8// Functions to use:
9// map, reduce, filter
10//
11// String functions that might be helpful:
12// contains("Some String", "g") --> returns true if "Some String" contains the character "g"
13// "Some String".hasSuffix("foo") --> returns true if "Some String" ends with "foo"
14
15// Create some test data for our purposes
16struct Person {
17 let name: String
18 let emailAddresses: [String]
19}
20
21let john = Person(name: "John Smith", emailAddresses: ["jsmith@gmail.com", "john@smith.org"])
22let bob = Person(name: "Bob Jones", emailAddresses: ["bob@jones.org"])
23let fred = Person(name: "Fred Barnes", emailAddresses: ["fbarnes@gmail.com", "fred@yahoo.com", "barnes@work.com"])
24
25let people = [john, bob, fred]
26
27// ---------------------------------------------------------------------------------------------
28
29// Exercise 1: Create a list of the peoples' names.
30let names: [String] = people.map { return $0.name}
31
32// Upon completion of exercise 1, this should evaluate to "true".
33names == ["John Smith", "Bob Jones", "Fred Barnes"]
34
35// ---------------------------------------------------------------------------------------------
36
37// Exercise 2: Create a "flattened" list containing all email addresses of all people.
38// NOTE: This should be a [String], not a [ [String] ].
39
40let emailAddressArray: [[String]] = people.map { return $0.emailAddresses }
41let emails: [String] = emailAddressArray.reduce([]){
42 return $0 + $1
43}// YOU FILL THIS IN
44
45// Upon completion of exercise 2, this should evaluate to "true".
46let expectEmails = ["jsmith@gmail.com", "john@smith.org",
47 "bob@jones.org",
48 "fbarnes@gmail.com", "fred@yahoo.com", "barnes@work.com"]
49emails == expectEmails
50
51// ---------------------------------------------------------------------------------------------
52
53// Exercise 3: Create a list of all people who have the letter "J" somewhere in their name.
54let peopleWithJ: [Person] = people.filter {
55 return contains($0.name, "J")
56}// YOU FILL THIS IN
57
58// Upon completion of exercise 3, these should evaluate to "true".
59peopleWithJ.count == 2
60peopleWithJ[0].name == "John Smith"
61peopleWithJ[1].name == "Bob Jones"
62
63// ---------------------------------------------------------------------------------------------
64
65// Silver Challenge: Create a list of all people who have an @gmail.com email address.
66let expectGmailPeople = [john, fred]
67let gmailPeople: [Person] = expectGmailPeople.filter {
68 return countElements($0.emailAddresses.filter {
69 return $0.hasSuffix("@gmail.com")
70 }) > 0
71}// YOU FILL THIS IN
72gmailPeople.count == 2
73gmailPeople[0].name == "John Smith"
74gmailPeople[1].name == "Fred Barnes"
75
76// ---------------------------------------------------------------------------------------------
77
78// Gold Challenge: Solve Exercise 2 again, this time without using reduce.
79// Hint: Look up the "join" function.
80let emailStrings: [String] = people.map {
81 join(",", $0.emailAddresses)
82}
83let emailStrings2: String = join(",", emailStrings)
84let goldChallengeEmails: [String] = split(emailStrings2, {$0 == ","}, maxSplit: Int.max, allowEmptySlices: false)
85goldChallengeEmails == expectEmails