问题描述
我有一个包含三行代码的文本文件,需要将每一行都用“,”分隔,因此我可以将每一行中的代码片段放入一个类中。每行我要上一堂课。
这是我想出的东西。我只是认为这是太多的代码,并且想找到一种简单的方法来做到这一点。
文本文件如下
character,stats,stats
weapon,stats
armor,stats
第一行的代码如下
class Characterfight(
var name : String,var race : String,var hitpoints :Int,var strength : Int,var agility : Int,){
override fun toString(): String {
return """Character
Name: ${name}
Race: ${race}
Hitpoints :${hitpoints}
Strength: ${strength}
Agility: ${agility}
""".trimMargin()
}
}
var characteRSStats = mutablelistof<Characterfight>()
var charStats = mutablelistof<String>()
val fileName: String = "src/main/kotlin/gimli.txt"
var characterInfo = mutablelistof<String>()
var lines = File(fileName).readLines()
for (line in lines){
val pieces = line.split("\n")
characterInfo.add(line)
}
charStats.add(characterInfo[0])
for (stat in charStats){
var statpieces = stat.split(",")
var charpieces = Characterfight(statpieces[0],statpieces[1],statpieces[2].toInt(),statpieces[3].toInt(),statpieces[4].toInt)
characteRSStats.add(charpieces)
}```
解决方法
为避免样板toString()
代码,请考虑使用data classes:
data class CharacterFight(var name: String,var race: String,var hitpoints: Int,var strength: Int,var agility: Int)
假设其他两个类别是
data class Weapon(val name: String,val value: Int)
data class Armor(val name: String,val value: Int)
可以通过以下方式进行CSV反序列化(使用destructuring declarations使代码更具可读性,但是仍然不能避免在某些传递的参数上进行明显的toInt()
转换):
fun deserializeCSV(fileName: String): Triple<CharacterFight,Weapon,Armor> {
val (characterInfo,weaponInfo,armorInfo) = File(fileName).readLines().map { it.split(",") }
val character = run { //create separate scope to avoid clash of name variables
val (name,race,hitpointsStr,strengthStr,agilityStr) = characterInfo
CharacterFight(name,hitpointsStr.toInt(),strengthStr.toInt(),agilityStr.toInt())
}
val weapon = run { //create separate scope to avoid clash of name variables
val (name,valueStr) = weaponInfo
Weapon(name,valueStr.toInt())
}
val armor = run { //create separate scope to avoid clash of name variables
val (name,valueStr) = armorInfo
Armor(name,valueStr.toInt())
}
return Triple(character,weapon,armor)
}
如果提供的CSV格式不是硬性要求,我建议改为使用JSON:
{"name":"Gimli","race":"dwarf","hitpoints":90,"strength":40,"agility":3}
{"name":"Axe","value":25}
{"name":"Plate male","value":85}
然后借助kotlinx.serialization库反序列化非常简单:
//don't forget to add `@Serializable` annotation to all deserializable classes
fun deserializeJSON(fileName: String): Triple<CharacterFight,armorInfo) = File(fileName).readLines()
val character: CharacterFight = Json.decodeFromString(characterInfo)
val weapon: Weapon = Json.decodeFromString(weaponInfo)
val armor: Armor = Json.decodeFromString(armorInfo)
return Triple(character,armor)
}