https://kotlinlang.org logo
#getting-started
Title
# getting-started
d

Daniele B

10/11/2020, 12:17 AM
I have a list of numbers:
val numbers = listOf(1,2,4,8,11,14)
I would like to create a new list with the differences between a number and the one that is 2 indexes before it. In this case the results would be:
val differencesTwoIndexesApart = listOf(3,6,7,6)
is there an easy way to do that with Kotlin high-order functions? or is an imperative for loop the best way?
a

akatkov

10/11/2020, 12:28 AM
val differencesTwoIndexesApart = numbers.windowed(3).map { it.last() - it.first() }
👏 9
e

ephemient

10/11/2020, 4:38 AM
also
Copy code
numbers.zip(numbers.drop(2)) { a, b -> b - a }
v

Vampire

10/11/2020, 9:30 AM
@ephemient that would throw away the first two numbers and then calculate the differences between subsequent numbers, that is not what OP wanted
e

ephemient

10/11/2020, 9:45 PM
@Vampire why do you think that? it clearly works according to @Daniele B's specification
v

Vampire

10/11/2020, 10:08 PM
Ah, sorry, confused with
zipWithNext
, you are totally right of course
d

Daniele B

10/12/2020, 3:37 AM
Many thanks to @akatkov and @ephemient! Both solutions fulfill the specification. Any comment about the efficiency of the two? Are they comparable?
e

ephemient

10/12/2020, 5:39 AM
it depends.
.windowed()
creates a new list for every window, while
.drop()
creates a copy of the trailing list
on
List<T>
specifically, that could be optimized to
.slice(2 until size)
which returns a view of the trailing list instead of a copy
if you're on an Array or ArrayList, you might as well just do
List(numbers.size - 2) { numbers[it + 2] - numbers[it] }
d

Daniele B

10/16/2020, 2:02 AM
@ephemient so does
windowed()
create a new list for every window or is it also a view?
e

ephemient

10/16/2020, 2:11 AM
new list
d

Daniele B

10/16/2020, 2:19 AM
cool! so that does it mean it reuses the same data?
e

ephemient

10/16/2020, 2:25 AM