如何在Kotlin字符串模板中嵌入循环
我们可以像在Kotlin字符串模板中一样简单地嵌套表达式运算符:
"List ${if (list.isEmpty()) "is empty" else "has ${list.size} items"}."
但是for
或不是表达式,不能像这样嵌套在模板中:
"<ol>${for (item in list) "<li>$item"}</ol>"
所以我正在寻找方便的方式来使用大模板内的循环。
到目前为止我发现的最简单的开箱即用的方法是用等效的joinToString调用替换循环:
"<ol>${list.joinToString("") { "<li>$it" }}</ol>"
要么
""" <ol>${list.indices.joinToString("") { """ <li id="item${it + 1}">${list[it]}""" }} </ol>""".trimIndent()
在喜好的情况下,也可以用辅助函数来模拟循环:
inline fun <T> forEach(iterable: Iterable<T>, crossinline out: (v: T) -> String) = iterable.joinToString("") { out(it) } fun <T> forEachIndexed1(iterable: Iterable<T>, out: (i: Int, v: T) -> String): String { val sb = StringBuilder() iterable.forEachIndexed { i, it -> sb.append(out(i + 1, it)) } return sb.toString() }
并像这样使用它们:
"<ol>${forEach(list) { "<li>$it" }}</ol>"
要么
""" <ol>${forEachIndexed1(list) { i, item -> """ <li id="item$i">$item""" }} </ol>""".trimIndent()
你可以简单地使用joinToString
来代替。
val s = """<ol> ${list.joinToString { "<li>$it</li>" }} </ol>""";
产量
<ol> <li>one</li> <li>two</li> ... </ol>