Thread
#stdlib
    s

    spand

    2 years ago
    Are there any generalized functions like joinToString ? Currently I just need something like a forEach but with a sideeffect between elements.
    g

    gian

    2 years ago
    Something like this?
    .zipWithNext().forEach { (a, b) -> }
    s

    spand

    2 years ago
    I cant quite get that to work ie.
    listOf(1,2,3).zipWithNext().forEach {  println(it.first); println("-"); println(it.second) }
    Gives
    1-22-3
    wasyl

    wasyl

    2 years ago
    There’s also
    Iterable<T>.joinTo
    where you can provide an appendable buffer to put elements into
    Czar

    Czar

    2 years ago
    @spand, I'm a bit confused, what did you want to get instead of
    1-2
    2-3
    ?
    s

    spand

    2 years ago
    1-2-3
    Czar

    Czar

    2 years ago
    Oh, I see, then @wasyl’s answer is correct
    s

    spand

    2 years ago
    Not really. His answer does not take the question into context
    I ended up making my own:
    private inline fun <T> Iterable<T>.intersperseEach(separator: () -> Unit = {}, before: () -> Unit = {}, after: () -> Unit = {}, action: (T) -> Unit): Unit {
        val ite = iterator()
        var first = true
        before()
        while (ite.hasNext()) {
            if (first) {
                first = false
            } else {
                separator()
            }
            action(ite.next())
        }
        after()
    }
    Seems like it fits in the stdlib imo.
    Czar

    Czar

    2 years ago
    Oh, I see, I'm a bit slow today it seems, sorry 🙂
    s

    spand

    2 years ago
    I just wanted to ask if there was another function in the stdlib that was close enough.
    wasyl

    wasyl

    2 years ago
    Yeah I just mentioned another method somewhat relevant to joining. But I’m curious what’s the use case for the method above? It just performs some side effects during iteration, right?
    s

    spand

    2 years ago
    The current case is printing line separators between elements in kotlinx.html ie.:
    <div></div>
    <hr />
    <div></div>
    Pretty standard stuff
    k

    Kristoffer Andersen

    2 years ago
    Maybe flatten it a little? I am just golfing, now 🙂
    val ite = iterator()
        before()
        if (!ite.hasNext()) { after(); return }
        action(ite.next())
        while (ite.hasNext()) {
            separator()
            action(ite.next())
        }
        after()
    s

    spand

    2 years ago
    And since I am not working with strings joinToString is no good
    Czar

    Czar

    2 years ago
    val result = mutableListOf<String>()
    
    val input = listOf(1, 2, 3)
    
    val iter = input.iterator()
    iter.forEachRemaining {
    	result.add(it.toString())
    	if (iter.hasNext()) result.add("-")
    }
    println(result) // gives: [1, -, 2, -, 3]
    Isn't this what you're looking for then?
    s

    spand

    2 years ago
    Yes that would work
    Czar

    Czar

    2 years ago
    fun <T> Iterable<T>.intersperseEach(
       separator: () -> Unit = {},
       before: () -> Unit = {},
       after: () -> Unit = {},
       action: (T) -> Unit
    ) {
       before()
       val iterator = iterator()
       iterator.forEachRemaining {
          action(it)
          if (iterator.hasNext()) separator()
       }
       after()
    }
    
    listOf("<div></div>", "<div></div>").intersperseEach(
    	separator = { println("<br />") },
    	action = ::println
    )
    // prints:
    // <div></div>
    // <br />
    // <div></div>
    s

    spand

    2 years ago
    https://youtrack.jetbrains.com/issue/KT-36647 if anyone wants to watch 😉
    Czar

    Czar

    2 years ago
    @spand I'm
    @Alexander_Czar
    on YT
    thanks for the attribution 🙂
    s

    spand

    2 years ago
    Credit where credit is due
    Derek Peirce

    Derek Peirce

    2 years ago
    Is there a point to
    before
    and
    after
    ? Those could each be replaced with
    also
    .
    s

    spand

    2 years ago
    Good point