【问题标题】:How to embed for loops in Kotlin string templates如何在 Kotlin 字符串模板中嵌入 for 循环
【发布时间】:2017-11-17 04:43:11
【问题描述】:

我们可以在 Kotlin 字符串模板中轻松嵌套 if 和 when 等表达式运算符:

"List ${if (list.isEmpty()) "is empty" else "has ${list.size} items"}."

但for 或while 不是表达式,不能像这样嵌套在模板中:

"<ol>${for (item in list) "<li>$item"}</ol>"

所以我一直在寻找在大型模板中使用循环的便捷方法。

【问题讨论】:

标签: string loops templates for-loop kotlin


【解决方案1】:

到目前为止,我发现的最简单的开箱即用方法是用等效的 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()

【讨论】:

    【解决方案2】:

    您可以简单地使用joinToString。

    val s = """<ol>
                 ${list.joinToString { "<li>$it</li>" }}
               </ol>""";
    

    输出

    <ol>
       <li>one</li>
       <li>two</li>
       ...
    </ol>
    

    【讨论】:

    • 抱歉,我不明白它与我的答案中的第一行代码有何不同。 )
    • @Vadzim 先生,我写我的时候没有看到你的答案。我发现我们是一样的......
    • 那么没有compaints。但我同时发布了问题和答案。真奇怪。 %)
    • @Vadzim 对不起,先生。我来自中国,英语不好。所以我回答问题的时间可能比你多。
    猜你喜欢
    • 2013-06-30
    • 1970-01-01
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多