我如何按行获取txt信息并将每行拆分为单独的类

问题描述

我有一个包含三行代码的文本文件,需要将每一行都用“,”分隔,因此我可以将每一行中的代码片段放入一个类中。每行我要上一堂课。

这是我想出的东西。我只是认为这是太多的代码,并且想找到一种简单的方法来做到这一点。

文本文件如下

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)
}