2013-11-12 4 views
3

У меня есть список значений и вы хотите уменьшить его до списка различий между последовательными членами. Есть ли лучший способ, чем это я придумал (тривиальный пример)?Получите различия между членами списка

val l1 = List(1,2,3,4,5,6) 

val diffs = (l1 zip l1.drop(1)).map{case (x,y) => y - x}.sum 
+0

'List (a1, a2, a3, ... An)' => '(a1 - a2) + (a2 - a3) +. .. + (aN-1 - aN) == a1 - aN' => 'diffs == l1.head - l2.last'. – senia

ответ

8

Я уверен, что я ответил на очень похожий вопрос раньше, но я не могу его найти. Во всяком случае, попробовать zipped как это более эффективно и дает более хороший синтаксис:

(l1 drop 1, l1).zipped.map(_-_).sum 
+0

Ницца, помещая отброшенную версию сначала в кортеж –

+0

Аккуратный. Также скользящие решения, как показано ниже, выглядят довольно медленно на специальных тестах, которые я пробовал. – Gavin

1

Вы можете использовать скольжение

l1.sliding(2).map { case Seq(a, b) => b - a } .sum 

Но это не намного короче. Также, если у вас есть список, вы можете использовать l1.tail вместо l1.drop(1).

я когда-то написал следующий метод расширения:

import collection.generic.CanBuildFrom 

implicit final class RichIterableLike[A, CC[~] <: Iterable[~]](val it: CC[A]) 
    extends AnyVal { 
    def mapPairs[B, To](fun: (A,A)=>B)(implicit cbf: CanBuildFrom[CC[A], B, To]): To = { 
    val b  = cbf(it) 
    val iter = it.iterator 
    if (iter.hasNext) { 
     var pred = iter.next() 
     while (iter.hasNext) { 
     val succ = iter.next() 
     b += fun(pred, succ) 
     pred = succ 
     } 
    } 
    b.result() 
    } 
} 

С этим:

l1.mapPairs(-_+_).sum 
+2

Использование 'drop (1)', а не 'tail' - лучший выбор, потому что безопасен для пустых последовательностей. Например, 'Nil.tail' вызывает исключение, но' Nil.drop (1) 'возвращает' Nil'. – DaoWen

+0

@ DaoWen да, это так. –

5

мне нравится использовать sliding для этого сценария использования:

val l1 = List(1,2,3,4,5,6) 
val diffs = l1.sliding(2).map{case List(x, y) => x - y}.sum 

попробовать его here ,

+0

+1 для этого сайта с плавающей точкой! –

Смежные вопросы