Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialBerry Loeffen
4,303 PointsAdding a function to the next challenge.
Adding the function bookDetails to the struct. Is this the way to do it or is there a shorter version possible? I don't think a Guard statement can be used here, so I used "else if let" statements. Any ideas? or is there just no shorter way to do this?
struct Book {
let title: String
let author: String
let price: String?
let pubDate: String?
init?(dict: [String: String]) {
guard let title = dict["title"], let author = dict["author"] else {return nil}
self.title = title
self.author = author
self.price = dict["price"]
self.pubDate = dict["pubDate"]
}
func bookDetails() -> String {
if let price = price, let pubDate = pubDate {
return "\(title), \(author), \(price), \(pubDate)"
}
else if let price = price {
return "\(title), \(author), \(price)"
}
else if let pubDate = pubDate {
return "\(title), \(author), \(pubDate)"
} else {
return "\(title), \(author)"}
}
}
1 Answer
gianpierovecchi
15,043 PointsYou should start concatenating the non optional string and then add the optional.. like:
func bookDetails() -> String {
var details = "\(title), \(author)"
if let price = price {
details += ", \(price)"
}
if let pubDate = pubDate {
details += ", \(pubDate)"
}
return details
}
Shortened with ternary operator:
func bookDetails() -> String {
return "\(title), \(author)" + (price != nil ? ", \(price)" : "") + (pubDate != nil ? ", \(pubDate)" : "")
}
But if you want a glimpse about how fun is the language, you can use closures and array methods to do the work for you:
func bookDetails() -> String {
return [title, author, price, pubDate].flatMap{$0}.joinWithSeparator(", ")
}
flatMap is a filtering function that returns an Array without the nil values (the parameter $0 in curly braces is a shortened syntax of a closure, if you didn't study it yet you will be surprised), and JoinWithSeparator in pretty obvious.
Have fun programming! :)
Greg Kaleka
39,021 PointsGreg Kaleka
39,021 PointsJust came across this. Gianpiero's answer is very elegant. Just to point this out, though - you definitely could use guard. It's a bit sticky, though. I'll show it to you "clean" and then walk through the logic. It's not the most elegant thing... but it works!