Akshdeep Singh
Akshdeep Singh

Reputation: 1457

How to initialise 'MutableMap' from constructor of data class in kotlin?

I have a data class which has a constructor like this (source):

data class MyDataClass (
    val myArr: ArrayList<Char>
) {
    constructor(n: Int): 
        this(
            ArrayList((0 until n).map { ('A' + it).toChar() })
        )
}

As an example:

println(MyDataClass(3).myArr)

would give me:

[A, B, C]

I want to modify my data class further like this:

data class MyDataClass (
    val myArr: ArrayList<Char>,
    val myMap: MutableMap<Char, MutableMap<String, String>>
) {
    constructor(n: Int): 
    this(
            ArrayList((0 until n).map { ('A' + it).toChar() }),
            mutableMapOf()
        )
}

Now, when I print the myMap like:

println(MyDataClass(3).myMap)

I get:

{}

Now, I want that instead of getting an empty MutableMap for myMap, I want to get a MutableMap like this:

println(MyDataClass(3).myMap)
{A={}, B={}, C={}}

How would I do that?

Upvotes: 0

Views: 3330

Answers (2)

CrazyFrog007
CrazyFrog007

Reputation: 364

You can do one of the following:

  1. Extracting the init logic into a companion function:
data class MyDataClass(
    val myArr: ArrayList<Char>,
    val myMap: MutableMap<Char, MutableMap<String, String>>
) {
    constructor(n: Int) : this(
        ArrayList(foo(n)),
        foo(n).map { it to mutableMapOf<String, String>() }.toMap().toMutableMap()
    )

    companion object {
        fun foo(n: Int) = (0 until n).map { ('A' + it) }
    }
}
  1. Add intermediate constructor
data class MyDataClass(
    val myArr: ArrayList<Char>,
    val myMap: MutableMap<Char, MutableMap<String, String>>
) {
    constructor(n: Int) : this(ArrayList((0 until n).map { ('A' + it) }))

    constructor(list: ArrayList<Char>) : this(
        list,
        list.map { it to mutableMapOf<String, String>() }.toMap().toMutableMap()
    )
}

Upvotes: 1

Naliwe
Naliwe

Reputation: 322

I'm not sure I completely understand the reasons behind this choice of constructor params, but I would say you only need one of your constructors, since everything is built from the int param you take in the explicit ctor. Going from there, I would simplify the code to look like this:

data class Thingamajigg(val n: Int) {
    val myArr: ArrayList<Char> = arrayListOf()
    val myMap: MutableMap<Char, MutableMap<String, String>> = mutableMapOf()

    init {
        (0..n).forEach { myArr.add('A' + it) }
        myArr.forEach { myMap[it] = mutableMapOf() }
    }
}

Does that fit your needs?

Upvotes: 1

Related Questions