Home > Blockchain >  Create csv file with Hashmap in Kotlin
Create csv file with Hashmap in Kotlin

Time:11-19

I am fairly new to kotlin, and have wanted to change the way to save my CSV file. Currently my Hashmap is :

private var Sdata:MutableMap<String, MutableList<String>> = mutableMapOf<String, MutableList<String>>()

and my data looks like this :

{a1 = [1:2:3:4, 1:2:3:4, ....], b2 = [1:2:3:4, 1:2:3:4,....]}

and my csv saving function:

binding.btnSave.setOnClickListener() {
        Sdata = viewModel.savehash
        Log.d(TAG, "CSV VIEW: ${Sdata.keys}")
        Log.d(TAG, "CSV VIEW: ${Sdata.values.size}")
        if(Sdata.keys.size != 0) {
            val csv = File(this.filesDir, "test1.csv") // Internal App storage

            val valuesSeparator = ","
            val lineTerminator = "\r\n"
            //write header, overwrite file if it has existed
            csv.writeText(
                Sdata.keys.joinToString(
                    separator = valuesSeparator,
                    postfix = lineTerminator
                )
            )
            val nRows = Sdata.values.maxOf { it?.size }    // size of list ar not all equal
            for (i in 0 until nRows) {
                val row = Sdata.values
                    .map { it.getOrElse(i) { "" }.trim() }
                    .joinToString(separator = valuesSeparator, postfix = lineTerminator)
                csv.appendText(row)
            }

            Toast.makeText(this, "Data Saved to Documents", Toast.LENGTH_SHORT).show()
        }
        else{
            Toast.makeText(this, "No Logged Data", Toast.LENGTH_SHORT).show()
        }
    }

converts my files to look like this : CSV FILE

I want to reiterate column values where column a1 has --> a1W, a1X, a1Y, a1Z and the values underneath are separated by the ":" delimters so that each single column is separated into 4 columns. Will this be difficult in Kotlin? Any help would be greatly appreciated thankyou!!

CodePudding user response:

To do that, you just need to slightly modify the way you create the headers row and the data rows.

For the header row, change the Sdata.keys.joinToString(...) into:

Sdata.keys
    .flatMap { listOf("${it}W", "${it}X", "${it}Y", "${it}Z") }
    .joinToString(separator = valuesSeparator, postfix = lineTerminator)

The flatMap call allows you to create a new list by converting each element (like a1) into a list of 4 elements (a1W, a1X...) and joining all those lists together into a big one.

For the data row, change the .map { it.getOrElse(i) { "" }.trim() } into:

.flatMap { it.getOrElse(i) { "" }.trim().split(":") }

CodePudding user response:

The following for loop instead of yours should do the trick (thanks @Joffrey for the hint):

for (i in 0 until nRows) {
    val row = Sdata.flatMap { it.getOrElse(1) { "" }.trim().split(":") }
        .joinToString(separator = valuesSeparator, postfix = lineTerminator)
    csv.appendText(row)
}

Basically, you split your 1:2:3:4 values into a list containing the four numbers. And then your code should do the rest.

  • Related