我对编程还很陌生,并且想知道是否有比我在这里完成的语法编辑更简洁的方法(确保它不会返回像1 bottleS这样的荒谬语句)?我在想也许是一条switch语句,但是我对实现一个语句还是不够熟悉,甚至无法确定这是否是最佳方法。谢谢!
func beerSong(withThisManyBottles totalNumberOfBottles : Int) -> String {
var lyrics : String = ""
for i in (3...totalNumberOfBottles).reversed() {
let newLine : String = "\n \(i) bottles of beer on the wall, \(i) bottles of beer. \n Take one down and pass it around, \(i - 1) bottles of beer on the wall.\n"
lyrics += newLine
}
lyrics += "\n 2 bottles of beer on the wall, 2 bottles of beer. \n Take one down and pass it around, 1 bottle of beer on the wall.\n"
lyrics += "\n 1 bottle of beer on the wall, 1 bottle of beer. \n Take one down and pass it around, no more bottles of beer on the wall.\n"
lyrics += "\n No more bottles of beer on the wall, no more bottles of beer. \n Go to the store and buy some more, 99 bottles of beer on the wall.\n"
return lyrics
}
print(beerSong(withThisManyBottles : 99))
答案 0 :(得分:1)
我会写一种方法来根据数字返回正确的措辞:
func bottles(for count: Int) -> String {
if count == 0 {
return "no more bottles"
} else if count == 1 {
return "1 bottle"
} else {
return "\(count) bottles"
}
}
然后,我将您的beerSong
方法重构为:
func beerBottleLine(for count: Int) -> String {
let countBottles = bottles(for: count)
let oneLess = bottles(for: count - 1)
let line = "\(countBottles) of beer on the wall, \(countBottles) of beer.\nTake one down and pass it around, \(oneLess) of beer on the wall."
return line
}
func beerSong(withThisManyBottles totalNumberOfBottles : Int) -> String {
let lyrics = (1...totalNumberOfBottles).reversed().map { beerBottleLine(for: $0)}.joined(separator: "\n")
return lyrics + "\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, \(totalNumberOfBottles) bottles of beer on the wall."
}
快速测试:
print(beerSong(withThisManyBottles: 5))
答案 1 :(得分:1)
这是我的看法。 rmaddy的代码对大多数数字进行两次beerBottleLine(for:)
计算(一次是“主”数字,一次是“少”数字)。诚然,这是一个绝对微小且本质上毫无意义的性能差异,但它演示了整洁的zip(a, a.dropLast())
模式的使用。
我还选择通过利用多行字符串文字,切换到更常规的标识符名称以及使用开关而不是三部分if
/ else if
/ else
来提高可读性梯子。
func bottlePhrase(for count: Int) -> String {
switch count {
case 0: return "no more bottles of "
case 1: return "1 bottle"
case _: return "\(count) bottles"
}
}
func beerSong(bottleCount: Int) -> String {
let bottlePhrases = (0...bottleCount)
.lazy
.reversed()
.map{ bottlePhrase(for: $0) + " of beer" }
let mainBody = zip(bottlePhrases, bottlePhrases.dropFirst())
.map { bottlePhrase, oneLessBottlePhrase in return """
\(bottlePhrase) on the wall, \(bottlePhrase).
Take one down and pass it around, \(oneLessBottlePhrase) on the wall.
"""
}
.joined(separator: "\n")
return mainBody + """
\nNo more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, \(bottleCount) bottles of beer on the wall.
"""
}
print(beerSong(bottleCount: 5))