Copilot Kotlin: Convert a list of numbers to string
Video: Copilot Kotlin: Convert a list of numbers to string by Taught by Celeste AI - AI Coding Coach
Kotlin: Convert a List of Numbers to a Comma-Separated String
numbers.joinToString(", "). One method, exactly the output you want. The Kotlin alternative toString.join(Java) or", ".join(...)(Python).
A small puzzle: take [1, 2, 3, 4, 5] and produce "1, 2, 3, 4, 5". Kotlin's joinToString does it cleanly with a single optional separator argument.
The Copilot prompt
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// Convert the list to a comma-separated string
Copilot generates:
val result = numbers.joinToString(separator = ", ")
println(result) // "1, 2, 3, 4, 5"
joinToString signature
fun <T> Iterable<T>.joinToString(
separator: CharSequence = ", ",
prefix: CharSequence = "",
postfix: CharSequence = "",
limit: Int = -1,
truncated: CharSequence = "...",
transform: ((T) -> CharSequence)? = null,
): String
Six parameters, all optional with sensible defaults. Use them:
listOf(1, 2, 3).joinToString()
// "1, 2, 3" (default separator is ", ")
listOf(1, 2, 3).joinToString(separator = " | ")
// "1 | 2 | 3"
listOf(1, 2, 3).joinToString(prefix = "[", postfix = "]")
// "[1, 2, 3]"
listOf(1, 2, 3).joinToString(separator = ", ", prefix = "[", postfix = "]")
// "[1, 2, 3]"
(1..1000).joinToString(limit = 5)
// "1, 2, 3, 4, 5, ..." (truncates after 5, with "..." marker)
limit shows the first n elements then a truncation marker (default "..."). Useful for logs of huge lists.
With a transform
val people = listOf(
Person("Alice", 30),
Person("Bob", 25),
Person("Charlie", 35),
)
val names = people.joinToString(", ") { it.name }
// "Alice, Bob, Charlie"
val descriptions = people.joinToString(", ") { "${it.name} (${it.age})" }
// "Alice (30), Bob (25), Charlie (35)"
The transform lambda runs on each element, returning a CharSequence. Lets you format complex objects without a separate map { ... }.joinToString() chain.
Versus map().joinToString()
people.map { it.name }.joinToString(", ")
// Equivalent, but allocates an intermediate List<String>
people.joinToString(", ") { it.name }
// One pass, no intermediate
The version with the transform is one allocation cheaper. For large lists, that matters.
On non-list iterables
// Map
val map = mapOf("a" to 1, "b" to 2)
val result = map.entries.joinToString(", ") { "${it.key}=${it.value}" }
// "a=1, b=2"
// Set
val set = setOf("apple", "banana")
println(set.joinToString()) // "apple, banana"
// String → its chars
"hello".toList().joinToString("-") // "h-e-l-l-o"
"hello".joinToString("-") { it.toString() } // "h-e-l-l-o" — directly on String
// Array
intArrayOf(1, 2, 3).joinToString(", ") // "1, 2, 3"
joinToString works on Iterable<T>, Array<T>, and primitive arrays. The signatures vary slightly but the API is the same.
Joining keys, values, or both for a Map
val pairs = mapOf("a" to 1, "b" to 2, "c" to 3)
pairs.keys.joinToString(", ")
// "a, b, c"
pairs.values.joinToString(", ")
// "1, 2, 3"
pairs.map { (k, v) -> "$k=$v" }.joinToString(", ")
// "a=1, b=2, c=3"
Or with the transform:
pairs.entries.joinToString(", ") { (k, v) -> "$k=$v" }
CSV output
val rows = listOf(
listOf("Alice", "30", "Engineer"),
listOf("Bob", "25", "Designer"),
)
val csv = rows.joinToString("\n") { row -> row.joinToString(",") }
println(csv)
// Alice,30,Engineer
// Bob,25,Designer
Two joinToString calls — outer joins rows with newlines, inner joins fields with commas.
For real CSV, watch out for fields containing commas, newlines, or quotes — they need quoting/escaping. For toy CSV like this, the bare joinToString is fine.
Common mistakes
Forgetting the separator default. joinToString() without args is ", "-separated, including a space. For tight output (1,2,3), pass "," explicitly.
Using String.join. That's a Java method that exists on Kotlin Strings too, but joinToString is more powerful (transform, limit, prefix/postfix).
joinToString then joinToString chain. For nested data, chaining is fine. For deep trees, write a recursive printer instead.
Concatenating with +. nums.fold("") { acc, n -> "$acc, $n" } works but produces , 1, 2, 3 (leading comma). Use joinToString.
limit = 5 without truncated. Shows "1, 2, 3, 4, 5, ...". Customise: truncated = "[and more]".
What's next
Episode 33: Filter an array. arrayOf(...).filter { ... } returns a List — one of the oddities of mixing arrays and the functional Kotlin stdlib.
Recap
numbers.joinToString(", ") for joining. Optional prefix, postfix, limit, truncated. Optional transform: (T) -> CharSequence to format each element inline (saves a map). Works on Iterable<T>, Array<T>, primitive arrays, and String. For nested joins, chain calls. For real CSV, use a library — joinToString doesn't escape special chars.
Next episode: filter an array.