F-string altirnative in Kotlin

In Python, one could simply do:

echo(f"test_{i}")

But how would you do that in Kotlin, if you can? I need variables automatically generated from the for loop integer.

https://kotlinlang.org/docs/reference/idioms.html#string-interpolation

val jsonArrayRequest = JsonArrayRequest(
                Request.Method.GET, url, null,
                Response.Listener { response ->
                    for (i in 0 until response.length()) {
                        val item: JSONObject = response.getJSONObject(i)
                        val item_location = item.getJSONArray("location")
                        val color = giveMarkerColor(item)
                        val point = LatLng(item_location.getDouble(0), item_location.getDouble(1))
                        runOnUiThread {
                            val mMarker_$i = mMap.addMarker(
                                MarkerOptions()
                                    .position(point)
                                    .icon(BitmapDescriptorFactory.defaultMarker(color))
                                    .title(item.getString("id"))
                                    .snippet(giveSnippet(item))
                            )
                        }

Yeah, nope, that’s not how it works. :frowning:

Please try to formulate your questions more precisely. You asked about string interpolation, I gave you reference to documentation since Kotlin already can do that and in much more neat way than python. Interpolation obviously does not work in variable names. You need to use collection, which has nothing to do with strings.

5 Likes

I’m not experienced with Python’s F-String, but it looks like it’s a short cut for variable interpolation. As @darksnake mentioned, Kotlin has that built into all normal strings (the documentation he linked should help).

fun main() {
    val fruits = listOf("Apple", "Orange", "Mango", "Pineapple", "Banana")
//sampleStart
fruits.forEachIndexed { index, name ->
  println("Fruit $name has index of $index and is ${name.length} characters long")
}
//sampleEnd
}

From your second example, it looks like you want to create variables with the name dynamically generated from the loop index (val mMarker_$i), not just print out that value. Is that right?

From this StackOverflow question, it looks like most of the advice from the Python users on this question is that this is not a good idea.

If you have some specific use case for adding variables at runtime to a class or instance then you will likely need to use bytecode manipulation–definitely harder than Pythons exec("%s=%s" % (k,v)).
Similar to the Python advice on this, I recommend avoiding dynamically creating variable names if the use case is local variables like what is shown in your example.

Fortunately, due to Kotlin’s non-dynamic nature code like this is impossible. As you only ever have one variable mMarker_... in scope at any time, there is no reason to want “dynamic” variable naming - store your results in a Map or List if you need to access them by index.

2 Likes

Yes, you’re correct and the only way that I can think of so that I can update the markers that are generated from JSON, is by using dynamically generated variables so I can update them.

How can I use Map or a List with GoogleMaps location markers? I don’t think you can, but I might be mistaken?

Maybe something like this?

val markers = mutableMapOf<Int, Marker>() // I don't know the correct type but you get the idea

val jsonArrayRequest = JsonArrayRequest(
                Request.Method.GET, url, null,
                Response.Listener { response ->
                    for (i in 0 until response.length()) {
                        val item: JSONObject = response.getJSONObject(i)
                        val item_location = item.getJSONArray("location")
                        val color = giveMarkerColor(item)
                        val point = LatLng(item_location.getDouble(0), item_location.getDouble(1))
                        runOnUiThread {
                            markers[i] = mMap.addMarker(
                                MarkerOptions()
                                    .position(point)
                                    .icon(BitmapDescriptorFactory.defaultMarker(color))
                                    .title(item.getString("id"))
                                    .snippet(giveSnippet(item))
                            )
                        }
2 Likes

Huh, thank you. That worked.