Skip to content

Instantly share code, notes, and snippets.

@carlynorama
Last active May 27, 2020 21:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlynorama/1d679c3cbf164250b971813418e6dd2c to your computer and use it in GitHub Desktop.
Save carlynorama/1d679c3cbf164250b971813418e6dd2c to your computer and use it in GitHub Desktop.
RW Closures Section
//: ## Episode 08: Closures & Collections
// --------------------------------------
class Student {
let name: String
var grade: Int
var pet: String?
var libraryBooks: [String]
init(name: String, grade: Int, pet: String? = nil, libraryBooks: [String]) {
self.name = name
self.grade = grade
self.pet = pet
self.libraryBooks = libraryBooks
}
func getPassStatus(lowestPass: Int = 50) -> Bool {
grade >= lowestPass
}
func earnExtraCredit() {
grade += 10
}
}
let chris = Student(name: "Chris", grade: 49, pet: "Mango", libraryBooks: ["The Book of Atrus", "Living by the Code", "Mastering Git"])
let sam = Student(name: "Sam", grade: 99, pet: nil, libraryBooks: ["Mastering Git"])
let catie = Student(name: "Catie", grade: 75, pet: "Ozma", libraryBooks: ["Hogfather", "Good Omens"])
let andrea = Student(name: "Andrea", grade: 88, pet: "Kitten", libraryBooks: ["Dare to Lead", "The Warrior's Apprentice"])
let students = [chris, sam, catie, andrea]
// --------------------------------------
/*:
## Challenge 1 - `forEach` & `map`
There are two `for` loops below.
Rewrite one of them using `forEach` and the other with `map`
*/
//for student in students {
// student.earnExtraCredit()
//}
students.forEach { $0.earnExtraCredit() }
//var classLibraryBooks: [[String]] = []
//for student in students {
// classLibraryBooks.append(student.libraryBooks)
let classBooks = students.map { $0.libraryBooks }
//let classBooks2: [String] = students.map {
// $0.libraryBooks.forEach(){ $0 }
//}
let bookList = classBooks.map { (books) in
print(books)
}
/*:
## Challenge 2 - compactMap
Replace the `for` loop below with compactMap.
It will filter out the `nil` values for you!
*/
var classPets: [String] = []
for student in students {
if let pet = student.pet {
classPets.append(pet)
}
}
let validPets = students.compactMap { s in
s.pet
}
let validPets2 = students.compactMap { $0.pet }
print(validPets, validPets2)
/*:
## Challenge 3 - flatMap
In Challenge 1 you created `libraryBooks`, an array of String arrays!
Try using flatMap to flatten all of the books into a single String array.
*/
let flatBooks: [String] = classBooks.flatMap { $0 }
print(flatBooks)
let flatBooks2: [String] = classBooks.flatMap { $0 }
print(flatBooks2)
let flatBooks3: Set = Set(classBooks.flatMap { $0 }.sorted())
print(flatBooks3)
let flatBooks4: Set = Set(classBooks.flatMap { $0 }.sorted(by: >))
print(flatBooks4)
let flatBooks5: Set = Set(classBooks.flatMap { $0 }.sorted(by: <))
print(flatBooks5)
print(flatBooks5.sorted())
print(flatBooks5.sorted(by: >))
print(flatBooks5.sorted(by: <))
//THIS IS THE BEST!!!
let classBooksFlat = Set(students.flatMap { $0.libraryBooks }).sorted()
print(classBooksFlat)
//: [⇐ Previous: 09 - filter, reduce, and sort](@previous)
//: ## Episode 10: Challenge - filter, reduce, and sort
/*:
## Challenge Time 😎
Create a constant array called `names` which contains some names as strings (any names will do — make sure there’s more than three though!). Now use `reduce` to create a string which is the concatenation of each name in the array.
*/
let names = ["Bonny", "George", "Linda", "Diane"]
let namesString = names.reduce("", +)
namesString
//var namesString2 = names.reduce("My dogs are called ") { message, name -> String in
// message += "\(name) and "
//}
//namesString2
//var namesString2 = names.reduce("My dogs are called ") { $0 += ("\($1) and ") }
//namesString2
//let array = ["Andrew", "Ben", "John", "Paul", "Peter", "Laura"]
//let joined = array.joined(separator: ", ")
/*:
Using the same `names` array, first filter the array to contain only names which have more than four characters in them, and then create the same concatenation of names as in the above exercise. (Hint: you can chain these operations together.)
*/
let names2 = ["Bob", "Bonny", "George", "Linda", "Joe", "Diane"]
//let dwarvesAfterM = arrayOfDwarfArrays.flatMap { dwarves -> [String] in
// dwarves.filter { $0 > "M" }
//}.sorted()
//var bothReducedAndFiltered = names.filter { $0.count > 5 }.reduce("", +)
//print(bothReducedAndFiltered)
var bFandR = names2.filter { (name) -> Bool in
name.count > 3
}.reduce("My pets are called ") { (message, name) -> String in
message + " and " + name
}
print(bFandR)
var bothReducedAndFiltered2 = names2.filter { $0.count > 3 }.joined(separator: " and ")
print(bothReducedAndFiltered2)
/*:
Create a constant dictionary called `namesAndAges` which contains some names as strings mapped to ages as integers. Now use `filter` to create a dictionary containing only people under the age of 18.
*/
let namesAndAges = ["Bob": 12, "Bonny": 43, "George": 29, "Linda": 10, "Joe": 16, "Diane": 92]
//var youths = namesAndAges.filter { (name, age) -> Bool in
// age < 18
//}
//var youths = namesAndAges.filter { $1 < 18 }
//good balance between clear and succint.
var youths = namesAndAges.filter { (_, age) in age < 18 }
print(youths)
var youths2 = namesAndAges.filter { $0.value < 18 }
print(youths2)
//interesting that the order is different.
/*:
Using the same `namesAndAges` dictionary, filter out the adults (those 18 or older) and then use `map` to convert to an array containing just the names (i.e. drop the ages).
*/
let adultNames = namesAndAges.filter { $0.value >= 18 }.map { $0.key }
print(adultNames)
let adultNames2 = namesAndAges.filter { (_, age) in age >= 18 }.map { (name, _) in name }//.sorted()
print(adultNames2)
//: [⇒ Next: 11 - Conclusion](@next)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment