Если у вас есть список значений и вы хотите свести все их к одному значению, применяя какую-то операцию. Вам нужен fold
, наиболее распространенным из них будет foldLeft
.
Как вы можете видеть в scaladoc . Этот метод получает начальное значение и комбинированную функцию.
Должно быть очевидно, что начальное значение должно быть zero
. И что комбинационная функция должна взять текущее накопление и добавить к нему цену текущего джинса.
Тем не менее, теперь у нас есть другая проблема, джинсы могут существовать или не существовать, поэтому мы используем опцию . В этом случае нам нужен способ сказать, если они существуют, дать мне их цену, если не дать значение по умолчанию (которое в этом случае имеет смысл быть другим zero
) .
И этоименно то, что Option.fold
дает нам.
Таким образом, мы заканчиваем чем-то вроде:
val sum = input.foldLeft(0) {
(acc, person) =>
acc + person.jeans.fold(ifEmpty = 0)(_.price)
}
Теперь, когда вам нужно среднее значение, вам нужно только разделить эту суммусо счетом.
Однако мы можем сделать счет в том же foldLeft
, просто чтобы избежать дополнительной итерации.
(Я изменил тип возвращаемого значения, а также price
свойство, до Double для обеспечения точных результатов) .
def avgPriceJeans(input: List[Person]): Double = {
val (sum, count) = input.foldLeft((0.0d, 0)) {
case ((accSum, accCount), person) =>
(
accSum + person.jeans.fold(ifEmpty = 0.0d)(_.price),
accCount + 1
)
}
sum / count
}