Home > Blockchain >  How can I loop over an array of sets/maps with varying data types
How can I loop over an array of sets/maps with varying data types

Time:12-10

I want to make it so that I keep my code dry and create 3 (or more, or less) buttons with somewhat the same structure. So I create a list of objects to loop over and put the data inside the object to use in several places in the AppButton.

I might think a bit too Pythonic, because that's my main language and I only recently started using Kotlin. What I normally do in Python:

app_buttons = [
    dict(
        text="....",
        icon="....",
        uri_string="....",
    ),
    ...
]

I've tried something similar in Kotlin with mapOf:

val appButtons = arrayOf(
    mapOf(
        "title" to getString(R.string.app_btn_example1),
        "icon" to R.drawable.ic_some_icon_1_64,
        "uriString" to "myapp://example1",
    ),
    ...
)

and then loop over them and getting from the map:

for (entry in appButtons) {
    buttons.add(
        AppButton(
            entry.get("text"),
            entry.get("icon"),
        ) {
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(entry.get("uriString"))).apply {
                val name = getString(R.string.saved_account_key)
                putExtra(name, sharedPref.getString(name, null))
            }
            startActivity(intent)
        }
    )
}

But then I get Type mismatch. Required String. Found {Comparable & java.io.Serializable}?. I don't know what types to put where...

Ok different approach, using setOf and destructuring:

val appButtons = arrayOf(
    setOf(
        getString(R.string.app_btn_example1),
        R.drawable.ic_some_icon_1_64,
        "myapp://example1",
    ),
    ...
)

for ((text, icon, uriString) in appButtons) {
    buttons.add(
        AppButton(
            text,
            icon
        ) {
            ...
        }
    )
}

But now I get the following:

Destructuring declaration initializer of type Set<{Comparable<*> & java.io.Serializable}> must have a 'component1()' function

Destructuring declaration initializer of type Set<{Comparable<*> & java.io.Serializable}> must have a 'component2()' function

Destructuring declaration initializer of type Set<{Comparable<*> & java.io.Serializable}> must have a 'component3()' function

How do I make this work? How do I create a basic list of objects and loop over them with the correct types? It feels so simple in Python. I'm clearly missing something.

CodePudding user response:

Rather than using maps, you should create a data class. For example:

data class ButtonModel(
     val title: String,
     val icon: Int,
     val uriString: String,
)

You can then create the array like this:

val appButtons = arrayOf(
    ButtonModel(
        title = getString(R.string.app_btn_example1),
        icon = R.drawable.ic_some_icon_1_64,
        uriString = "myapp://example1",
    ),
    ...
)

Or without the parameter labels if you prefer:

val appButtons = arrayOf(
    ButtonModel(
        getString(R.string.app_btn_example1),
        R.drawable.ic_some_icon_1_64,
        "myapp://example1",
    ),
    ...
)

Then, rather than getting them with get or [], you can just use the dot syntax:

buttons.add(
    AppButton(
        entry.text,
        entry.icon,
    ) {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(entry.uriString)).apply {
            val name = getString(R.string.saved_account_key)
            putExtra(name, sharedPref.getString(name, null))
        }
        startActivity(intent)
    }
)
  • Related