is there are nicer way of writting the following: ...
# announcements
r
is there are nicer way of writting the following:
Copy code
val list = mutableListOf()
var parent = map[current]
while(parent != null){
  list.add(parent)
  parent = map[parent]
}
I have the feeling there is a functional equivalent but I cannot come up with what it is
a
recursion comes to my mind
r
japp but I figured there is a function for this. Seems like a standard problem
that was my first guess but I don't see how I can fold
a
i've removed it, because there is nothing to fold over
so your best bet is recursion
r
hm...
a
if you do it right, you can make it as fast as the
while
-loop way: https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions
r
I am not a functional purist 🙂 in the end tailrecursion is optimised to the while above so I can write the while from the beginning
I'll search a bit and will come back if I found a solution
d
Looks like
generateSequence
would fit nicely here:
Copy code
fun main(args: Array<String>) {
    val initial = 0
    val map: Map<Int, Int?> = mapOf(
            0 to 2,
            2 to 1,
            1 to 3,
            3 to null
    )
    generateSequence(initial) { map[it] }.toList()
}
Code above prints
[0, 2, 1, 3]
👍 7
r
the thing is, it does not need to be the first key
I am not familiar with generateSequence, how would I need to adopt it?
d
generateSequence returns a sequence by repeatedly applying the function until it returns null
👍 1
r
ah.. damit, did not see initial 😄
unfortunate that it is much slower than the while loop 😞
d
Why do you think so? Essentially, it creates intermediate object (
GeneratorSequence
), then takes iterator from it (which will just delegate to passed function along with some simple conditional checks) and uses it to iterate over sequence in a usual way. Overhead shouldn't be very significant, unless you absolutely need every bit of a performance -- in such case yes, you will have to sacrifice code conciseness and readability for performance (which is extremely rare case, tbh)
r
I just made a quick benchmark 😉 nothing serious though
but still, quite a difference, following a sample: generateSequence1522.179 flatMap: 1412.807 while: 10.216 while: 2.104 generateSequence:356.357 flatMap: 345.54 flatMap: 336.826 while: 3.005 generateSequence:338.329
the numbers are System.nanoTime()/1000f
I think the numbers are significant enough that I can neglect my ragged setup