|
/*: |
|
# Monday Stretch Problem 5.1 |
|
## Hashtags |
|
### Instructions - Hashtags |
|
- Build a `Restaurant` model object with `name`, `streetAddress`, `city`, `state`, and `reviews` properties. |
|
- Build a `Review` model object with a `username` and `text` property. |
|
- Instantiate an array of `Restaurant` and `Review` objects. Make sure that each `Restaurant` object holds an array of reviews. Add hashtags to some of your reviews or restaruant descriptions. (Use Yelp or Google to help you come up with `Restaurants` and `Reviews`). |
|
- Add a `hashtags` computed property to the `Restaurant` object that returns an array of any hashtags in the `Restaurant` or `Review`. |
|
`- Check your computed property by printing a list of hashtags of each review and restaurant. |
|
|
|
### Instructions - Searching |
|
- Add a `SearchableObject` protocol with one function `matchesSearchTerm(searchTerm: String)`. |
|
- Implement the function on both model objects. |
|
- Demonstrate your search by printing a list of `Restaurants` that match a variety of search terms. |
|
*/ |
|
|
|
import Foundation |
|
|
|
protocol SearchableObject { |
|
func matchesSearchTerm(searchTerm: String) -> Bool |
|
} |
|
|
|
struct Restaurant: SearchableObject { |
|
let name: String |
|
let streetAddress: String |
|
let city: String |
|
let state: String |
|
let reviews: [Review] |
|
var hashtags: [String] { |
|
get { |
|
var hashtagCollector = [String]() |
|
|
|
reviews.forEach { hashtagCollector.append(contentsOf: $0.hashtags) } |
|
|
|
return hashtagCollector |
|
} |
|
} |
|
|
|
func matchesSearchTerm(searchTerm: String) -> Bool { |
|
let cleanSearchTerm = searchTerm.lowercased() |
|
|
|
for hashtag in hashtags where hashtag.lowercased() == cleanSearchTerm { |
|
return true |
|
} |
|
|
|
for review in reviews where review.matchesSearchTerm(searchTerm: cleanSearchTerm) { |
|
return true |
|
} |
|
|
|
return false |
|
} |
|
} |
|
|
|
struct Review: SearchableObject { |
|
let username: String |
|
let text: String |
|
var hashtags: [String] { |
|
get { |
|
let words = text.components( |
|
separatedBy: .whitespacesAndNewlines |
|
) |
|
|
|
return words.filter { $0.starts(with: "#") } |
|
} |
|
} |
|
|
|
func matchesSearchTerm(searchTerm: String) -> Bool { |
|
let cleanSearchTerm = searchTerm.lowercased() |
|
return text.contains(cleanSearchTerm) || hashtags.contains(cleanSearchTerm) |
|
} |
|
} |
|
|
|
let garrettReviewsCapriottis = Review(username: "beerguy", text: "dude, they forgot my order again! well, at least they gave me some free sandwich coupons I can use next time. #coupon #sandwich") |
|
|
|
let capriottis = Restaurant(name: "Capriotti's", streetAddress: "123 Digital Dr.", city: "Lehi", state: "Utah", reviews: [garrettReviewsCapriottis, Review(username: "Dwight", text: "GET THE MEATBALL SUB #meatballs")]) |
|
|
|
let dwightAtChickFilA = Review(username: "Dwight", text: "too much sodium #LOSODIUM") |
|
|
|
let chickFilA = Restaurant(name: "Chick-Fil-A", streetAddress: "134 Digital Dr.", city: "Lehi", state: "Utah", reviews: [Review(username: "Theo", text: "i love the app! #mobileorder #awesome"), Review(username: "Sean", text: "they gave me a free sandwich because I was waiting forever #awesome"), dwightAtChickFilA]) |
|
|
|
print(capriottis.hashtags) // ["#coupon", "#sandwich", "#meatballs"] |
|
print(chickFilA.hashtags) // ["#mobileorder", "#awesome", "#awesome", "#LOSODIUM"] |
|
|
|
print(chickFilA.matchesSearchTerm(searchTerm: "sandwich")) // true |
|
print(chickFilA.matchesSearchTerm(searchTerm: "fruit")) // false |
|
print(chickFilA.matchesSearchTerm(searchTerm: "#LOSODIUM")) // true |
|
print(chickFilA.matchesSearchTerm(searchTerm: "#losodium")) // true |
|
print(chickFilA.matchesSearchTerm(searchTerm: "#salad")) // false |