Kotlin练习:美化酒水菜单

/*
读取酒水订单文件,让酒水分类显示。
并且订单边缘对齐,酒水名首字母大写
酒水订单文件:
shandy,Dragon's Breath,5.91
elixir,shirley's temple,4.12
meal,goblet of la croix,1.22
desert dessert,pickled camel hump,7.33
elixir,iced boilermaker,11.22

完成后的输出应该像这样:
*** Welcome to Taernyl's Folly ***
          ~[shandy]~
Dragon's Breath...............5.91
          ~[elixir]~
Iced Boilermaker.............11.22
Shirley's Temple..............4.12
           ~[meal]~
Goblet of La Croix............1.22
      ~[desert dessert]~
Pickled Camel Hump............7.33
*/

import java.io.File
import java.util.*

//酒馆名称
const val TAVERN_NAME = "Taernyl's Folly"


//读取菜单文件
val menuList = File("data/tavern-menu-items")
    .readText() //返回 String 类型数据
    .split("\r\n") //注意此处需要用\r\n

fun main() {
    println("*** Welcome to $TAVERN_NAME ***")

    val menu = formatMenu(menuList)
    menu.forEach { line ->
        println(line)
    }
}

//不用首字母大写的单词
var lowercaseWords = setOf("a", "of", "or", "and")

//返回格式化后的菜单
fun formatMenu(menuData: List<String>): List<String> {
    val subList = mutableListOf<String>()
    var width = 0
    for (line in menuData) {
        val (kind, drink, price) = line.split(',')
        val length = drink.length + price.length
        if (length > width) {
            width = length
        }
        //直接在这里查询是否有同种类的订单,归类整理,以及将酒水字母大写
        val i = subList.indexOf(kind)
        if (i == -1) {
            subList.add(kind)
            subList.add(capitalString(drink, lowercaseWords))
            subList.add(price)
        } else {
            //每次始终在找到的数据后插入(从后向前倒着插:none、价格、酒水名)
            //插入完顺序为:(原种类名)、酒水名、价格、none
            //此处插入一个 none 标志占位,以便将来以 3 为间隔对每个种类和订单做不同处理
            subList.add(i + 1, "none")
            subList.add(i + 1, price)
            subList.add(i + 1, capitalString(drink, lowercaseWords))
        }
    }

    //获得首行长度
    val standardWidth = "*** Welcome to $TAVERN_NAME ***".length
    //若订单长度比首行至少短5个字符,填充点与首行边缘对齐;否则直接在两项之间填充5个点
    width = if (width + 5 <= standardWidth) standardWidth else (width + 5)

    //遍历子项列表,生成新菜单
    val menuList = mutableListOf<String>()
    val size = subList.size
    for (i in 0 until size step 3) {
        if (subList[i] != "none") {
            val kindLine = getKind(width, subList[i])
            menuList.add(kindLine)
        }
        var menuLine = subList[i + 1]
        menuLine += getDot(width, subList[i + 1], subList[i + 2])
        menuLine += subList[i + 2]
        menuList.add(menuLine)
    }
    return menuList
}

//返回适当数量的点字符串
fun getDot(width: Int, drink: String, price: String): String {
    var dot = ""
    while (drink.length + price.length + dot.length < width) {
        dot += '.'
    }
    return dot
}

//将字串中的各个单词首字母大写
//参数:字串,无需大写的字串集合
fun capitalString(str: String, lowercaseWords: Set<String>): String {
    var newStr = ""
    val list = str.split(' ')
    list.forEach { s ->
        //如果是不必大写的单词则不写
        newStr += if (lowercaseWords.contains(s)) s else s.replaceFirstChar {
            if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
        }
        newStr += ' '
    }
    //去除末尾空格
    newStr.take(newStr.length - 1)
    return newStr
}

//返回居中的酒水分类字符串
fun getKind(width: Int, kind: String): String {
    var line = "~[$kind]~"
    var spaceCount = (width - line.length) / 2
    //在字符串前后添加空格
    while (line.length < width) {
        line = ' ' + line
        if(line.length >= width) break
        line += ' '
    }
    return line
}

运行效果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值