Я изо всех сил, чтобы найти простой функциональный способ превратитьКак суммировать список целых чисел и сохранить каждый шаг в новый список?
val ints = List(1, 2, 3, 4, 5) into List(1, 3, 6, 10, 15)
Как это можно сделать?
Я изо всех сил, чтобы найти простой функциональный способ превратитьКак суммировать список целых чисел и сохранить каждый шаг в новый список?
val ints = List(1, 2, 3, 4, 5) into List(1, 3, 6, 10, 15)
Как это можно сделать?
Эта операция называется prefix sum, cumulative sum, or inclusive scan, более обобщенная функция более высокого порядка обычно называется scan
. Scala предоставляет scan
как часть своей библиотеки коллекций:
ints.scan(0)(_ + _).tail
Вы можете использовать foldLeft
следующим образом:
scala> List(1,2,3,4,5).foldLeft(List.empty[Int]) { case (acc, next) =>
| acc :+ next + acc.lastOption.getOrElse(0)
| }
res6: List[Int] = List(1, 3, 6, 10, 15)
В частичной функции (acc, next)
, acc
является в настоящее время накоплено список, который начинается как List.empty[Int]
и next
является следующее значение в предоставленном списке, начиная с 1
,
OP сказал «* простой * -функционала :) –
Простота относительна.: P – Eric
ints.foldLeft(List[Int]())((acc,elem)=>elem+acc.headOption.getOrElse(0)::acc)
О, продолжай, другой способ кожи кошки:
ints.drop(1).foldLeft(List(ints.head))((acc,elem)=>elem+acc.head::acc).reverse
Благодаря Ли ответ я изменил его
ints.tail.scan(ints.head)(_ + _)
Немного дольше, но он рассматривает первый элемент как начальное состояние.
, используйте 'ints.drop (1) ...', тогда он не будет генерировать исключение, если 'ints' пуст. - –
Я думаю, что ответы @Lee намного проще читать –
Это также подвержено исключениям, если коллекция пуста. – stefanobaghino
Короткий и простой, как я надеялся, хотя вызов сканирования с начальным состоянием по умолчанию в качестве первого элемента списка будет еще лучше – MaciejF
Like ints.scan (_ + _) – MaciejF
К сожалению, я не думаю, что есть эквивалент [Haskell's 'scanl1'] (https://hackage.haskell.org/package/base-4.9.1.0/docs/Prelude.html#v:scanl1), как есть ['fold'] (http://scala-lang.org/api/current/scala/collection/Seq.html#fold [A1>: A] (z: A1) (op: (A1 , A1) => A1): A1)/['reduce'] (http://scala-lang.org/api/current/scala/collection/Seq.html#reduce [A1>: A] (op :(A1, A1) => A1): A1) –