Are there any generalized functions like joinToStr...
# stdlib
s
Are there any generalized functions like joinToString ? Currently I just need something like a forEach but with a sideeffect between elements.
g
Something like this?
Copy code
.zipWithNext().forEach { (a, b) -> }
s
I cant quite get that to work ie.
Copy code
listOf(1,2,3).zipWithNext().forEach {  println(it.first); println("-"); println(it.second) }
Gives
Copy code
1-22-3
w
There’s also
Iterable<T>.joinTo
where you can provide an appendable buffer to put elements into
c
@spand, I'm a bit confused, what did you want to get instead of
Copy code
1-2
2-3
?
s
1-2-3
c
Oh, I see, then @wasyl’s answer is correct
s
Not really. His answer does not take the question into context
I ended up making my own:
Copy code
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.
c
Oh, I see, I'm a bit slow today it seems, sorry 🙂
s
I just wanted to ask if there was another function in the stdlib that was close enough.
w
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
The current case is printing line separators between elements in kotlinx.html ie.:
Copy code
<div></div>
<hr />
<div></div>
Pretty standard stuff
k
Maybe flatten it a little? I am just golfing, now 🙂
Copy code
val ite = iterator()
    before()
    if (!ite.hasNext()) { after(); return }
    action(ite.next())
    while (ite.hasNext()) {
        separator()
        action(ite.next())
    }
    after()
👍 1
s
And since I am not working with strings joinToString is no good
c
Copy code
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?
👍 1
s
Yes that would work
c
Copy code
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
https://youtrack.jetbrains.com/issue/KT-36647 if anyone wants to watch 😉
c
@spand I'm
@Alexander_Czar
on YT
👍 1
thanks for the attribution 🙂
s
Credit where credit is due
d
Is there a point to
before
and
after
? Those could each be replaced with
also
.
s
Good point