2015-08-06 10 views
1

Мой список Scala содержит следующие элементы:Вычитание соседние элементы списка

val A = List(12,1,34,34,45,56,7) 

теперь я хочу, чтобы вычитать список, как показано ниже:

List((12-1),(1-34),(34-34),(34-45),(45-56),(56-7)) 

так окончательный результат будет:

val result = List(11,-33,0,-11,-11,49) 

ответ

1

Просто бросить еще один вариант в смеси:

(A zip A.drop(1)).map({ case (a, b) => a - b }) 

Это дает вам немного больше безопасности, чем тип sliding потому Tuple2 шифрует тот факт, что элементы промежуточной коллекции являются пары.

+3

Вы можете использовать 'drop (1)' вместо 'tail', чтобы получить еще большую безопасность. 'tail' на' Nil' выдает исключение. – senia

+0

Спасибо, обновлено. Как глупо от меня. Иногда мне интересно, почему такие неприятные вещи, как 'tail', даже существуют ... –

-2

Ну, за этим стоит подумать:

for(int i=0; i<list.length-1; i++){ 
list[i]= list[i]-list[i+1]; 
} 

Теперь просто добавьте мелкие детали мусора, такие как результат настройки к окончательным значениям, и вы золотые.

4

Я думаю, что вам нужно sliding (группы элементов в блоках фиксированного размера пропусканием «скользящего окна» над ними):

A.sliding(2,1).toList.map(x => x(0) - x(1)) 
+3

'1' - это шаг по умолчанию, поэтому' .sliding (2) 'достаточно. –

+0

@ ChrisMartin этого не знал, спасибо! – jarandaf

+1

У вас есть проблема с одиночными списками. Вам нужно либо добавить '.filter (_. Size> 1)' перед 'map', либо заменить' map' на '.collect {case List (x, y) => x - y}'. –

1

Вы можете сделать:

val list = List(12, 1, 34, 45) 
list.sliding(2).map { 
case a :: b :: Nil => a - b 
}.toList 

Он должен вернуть то, что вы необходимость.

+1

Вы можете использовать 'collect' вместо' map', чтобы избежать исключения в 'List (12)'. – senia

+0

Вау, ты прав. Я ожидал 'List (12) .sliding (2)', чтобы вернуть пустой итератор. – ntn

3

И давайте не забывать zipped:

val A = List(12,1,34,34,45,56,7) 
(A,A.drop(1)).zipped.map(_-_) 
0

Я не впечатлен выступлением на молнии/карты решений. Это может быть сделано с помощью простого итератора, переопределяя метод next(). Но я предпочитаю потоки

def subNeighbours(xs: List[Int]): Stream[Int] = xs match { 
    case x :: y :: rest => (x - y) #:: subNeighbours(y :: rest) 
    case _ => Stream.Empty 
} 

(subNeighbours(A)).toList 

Входы и выходы:

  • List(12, 1, 34, 34, 45, 56, 7) =>List(11, -33, 0, -11, -11, 49)
  • List(1, 3, 2, 9, 0, 5) =>List(-2, 1, -7, 9, -5)
  • List(1) =>List()
  • List() =>List()

Потоковое решение проходит только один раз.

+1

На самом деле, это решение медленнее, чем' zip'/'zipped' решения. –

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