Итак, годовой год - это просто:
def yearly(data: List[Option[Double]], balance: Long): Double = {
val interest = year.flatten
interest.map(_ * balance).sum / interest.size
}
Вам не нужно отправлять все годы, а индекс только для того, чтобы посмотреть на него (а произвольный доступ для List
- это не то, что выдолжен сделать так или иначе), поэтому я настроил параметры соответственно.Он также должен возвращать Double
вместо Long
.
.flatten
здесь превращает List[Option[Double]]
в List[Double]
, выбрасывая те опции, которые None
, и распаковывая остальные в Double
..map
пересекает список и вызывает функцию для каждого элемента (_
является сокращением для аргумента, который является текущим элементом списка).Затем мы складываем все вместе .sum
и делим на размер (эта последняя часть кажется неправильной, я не знаю, почему вы хотите сделать это, кстати).
Обратите внимание, что .flatten
, .map
, .sum
и .size
каждый пересекает один и тот же список, который может считаться расточительным.Если year
- это список месяцев, а их около 12, это не имеет большого значения, и я призываю вас сделать это таким образом для выразительности.Но если мы говорим о миллиардах элементов, возможно, извлеченных из удаленного хранилища, это может стать недопустимым.Для этого случая всегда есть .foldLeft
:
val (total, size) = data.foldLeft((0, 0)) {
case ((total, size), Some(elem)) => (total + elem*balance, size + 1)
case (passThrough, _) => passThrough
}
total/size
Это то же самое, что и в первой версии, но только с одним проходом по списку..foldLeft
пересекает список, как .map
, но вместо того, чтобы просто передать текущий элемент списка в вашу функцию, он передает то, что возвратил в прошлый раз (или начальное значение, вы задаете его в качестве параметра для первого вызова), и текущий элемент, и, в конце концов, вы получите результат последнего выполнения функции, а не весь список.
Теперь, к составлению.Вы хотите начать с баланса и проходить каждый год, применяя трансформацию..foldLeft
делает именно это:
data.foldLeft(balance) { case (balance, year) => balance + yearly(year, balance) }