快速开关声明

时间:2018-07-11 02:19:29

标签: swift for-loop switch-statement

我对编程还很陌生,并且想知道是否有比我在这里完成的语法编辑更简洁的方法(确保它不会返回像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))

2 个答案:

答案 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))