Предположим, у меня есть список номеров. Как преобразовать список в список их «дельт» - попарных разностей последующих чисел?
Например: учитывая List(5, 2, 1, 1) я хотел бы получить List(3, 1, 0)
List(5, 2, 1, 1)
List(3, 1, 0)
Правильный ответ:
(xs, xs drop 1).zipped.map(_-_)
И он даже не взорвется, когда вы передадите ему пустой или однозначный список.
List(5,2,1,1).sliding(2).map(pair => pair(0) - pair(1))
Два других возможных решения:
list.zip(list.drop(1)).map { case (x, y) => x - y } // in case you don't like the extractor method of dealing with Tuples list.zip(list.drop(1)).map(p => p._1 - p._2)
Для всех, кто предпочитает для понимания по картам, не возражает против экстракторов и любит называть промежуточные результаты:
for (List(current, next) <- list.sliding(2); delta = current - next) yield delta
Это не очень эффективно (создание списка из двух элементов для каждой пары соседних чисел), но
list.sliding(2).map(x=>(x(0)-x(1)))
должен дать вам то, что вы хотите.
Рекурсивный способ:
scala> def calcDeltas(l:List[Int]):List[Int] = l match { | case Nil => Nil | case x::Nil => Nil | case x::y::Nil => (x-y)::Nil | case x::y::tail => (x-y)::calcDeltas(y::tail) | }