1

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
}

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Thank you for the answer. Actually I am using this in a loop hence cannot use the first approach you have suggested :) But this helped me get i the right direction so I can properly insert data in list and map without getting any empty entries.
Instead of using loops and mutable datastructures. You may be able to use the map function to do what you want. Difficult to see without your code though. :)
I added the function for which I am trying to use the data structure. I could not see how would I use map to avoid loops. Would definitely like to know :-)
Ah, you're parsing a CSV. Updated the answer. Good luck ;-)
Yes, the CSV parser is handling that automatically because I provided the withHeader() option when creating the parser - it knows the first row provides the keys and the current row provides be the values.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.