Я написал простую операцию группировки (на самом деле Groupable
trait
с неявным преобразованием из Iterable
), которая позволила бы вам сгруппировать ваши сделки по их currency
:
trait Groupable[V] extends Iterable[V] {
def groupBy(f: V => K): MultiMap[K, V] = {
val m = new mutable.HashMap[K, Set[V]] with mutable.MultiMap[K, V]
foreach { v => m add (f(v), v) } //add is defined in MultiMap
m
}
}
implicit def it2groupable(it: Iterable[V]): Groupable[V] = new Groupable[V] {
def elements = it.elements
}
Таким образом, Groupable
просто предоставляет способ извлечения ключа из каждого элемента в Iterable
и затем группирует все такие элементы, которые имеют один и тот же ключ. Итак, в вашем случае:
//mm is a MultiMap[Currency, Trade]
val mm = trades groupBy { _.currency }
Теперь вы можете делать довольно простые mapElements
(mm
- это Map
) и foldLeft
(или /:
) - хорошо стоит понять оператор foldLeft
, поскольку он обеспечивает чрезвычайно сжатые агрегации по коллекциям ) чтобы получить сумму:
val sums: Map[Currency, Int] = mm mapElements { ts =>
(0 /: ts) { (sum,t) => sum + t.notional }
}
Извините, если я сделал несколько ошибок в этой последней строке. ts
- это значения mm
, которые (конечно) Iterable[Trade]
.