Piyush Doke
Piyush Doke

Reputation: 145

Kotlin Creating List<List<Map<String, String>>>

I am trying to return List<List<Map<String, String>>> from a function in kotlin. I'm new to kotlin.

Edit1

Here's how I am attempting to to this

val a = mutableListOf(mutableListOf(mutableMapOf<String, String>()))

The problem with the above variable is, I am unable to figure out how to insert data into this variable. I tried with this:

val a = mutableListOf(mutableListOf(mutableMapOf<String, String>()))
val b = mutableListOf(mutableMapOf<String, String>())
val c = mutableMapOf<String, String>()
c.put("c", "n")
b.add(c)
a.add(b)

This is giving me:

[[{}], [{}, {c=n}]]

What I want is [[{c=n}]]

Can someone tell me how I can insert data into it?

The end goal I am trying to achieve is to store data in the form of List<List<Map<String, String>>>

EDIT 2

The function for which I am trying to write this dat structure:

fun processReport(file: Scanner): MutableList<List<Map<String, String>>> {
    val result = mutableListOf<List<Map<String, String>>>()
    val columnNames = file.nextLine().split(",")
    while (file.hasNext()) {
        val record = mutableListOf<Map<String, String>>()
        val rowValues = file.nextLine()
            .replace(",(?=[^\"]*\"[^\"]*(?:\"[^\"]*\"[^\"]*)*$)".toRegex(), "")
            .split(",")
        for (i in rowValues.indices) {
            record.add(mapOf(columnNames[i] to rowValues[i]))
            print(columnNames[i] + " : " + rowValues[i] + "   ")
        }
        result.add(record)
    }
    return result
}

Upvotes: 1

Views: 1246

Answers (1)

Adam Millerchip
Adam Millerchip

Reputation: 23091

You don't need to use mutable data structures. You can define it like this:

fun main() {
    val a = listOf(listOf(mapOf("c" to "n")))
    println(a)
}

Output:

[[{c=n}]]

If you wanted to use mutable data structures and add the data later, you could do it like this:

fun main() {
    val map = mutableMapOf<String, String>()
    val innerList = mutableListOf<Map<String, String>>()
    val outerList = mutableListOf<List<Map<String, String>>>()

    map["c"] = "n"
    innerList.add(map)
    outerList.add(innerList)

    println(outerList)
}

The output is the same, although the lists and maps are mutable.


In response to the 2nd edit. Ah, you're parsing a CSV. You shouldn't try to do that yourself, but you should use a library. Here's an example using Apache Commons CSV

fun processReport(file: File): List<List<Map<String, String>>> {
    val parser = CSVParser.parse(file, Charset.defaultCharset(), CSVFormat.DEFAULT.withHeader())
    return parser.records.map {
        it.toMap().entries.map { (k, v) -> mapOf(k to v) }
    }
}

For the following CSV:

foo,bar,baz
a,b,c
1,2,3

It produces:

[[{foo=a}, {bar=b}, {baz=c}], [{foo=1}, {bar=2}, {baz=3}]]

Note that you can simplify it further if you're happy returning a list of maps:

fun processReport(file: File): List<Map<String, String>> {
    val parser = CSVParser.parse(file, Charset.defaultCharset(), CSVFormat.DEFAULT.withHeader())
    return parser.records.map { it.toMap() }
}

Output:

[{foo=a, bar=b, baz=c}, {foo=1, bar=2, baz=3}]

I'm using Charset.defaultCharset() here, but you should change it to whatever character set the CSV is in.

Upvotes: 1

Related Questions