```inline fun <T, K, R> Grouping<T, K>...
# announcements
n
Copy code
inline fun <T, K, R> Grouping<T, K>.fold(
    initialValueSelector: (key: K, element: T) -> R,
    operation: (key: K, accumulator: R, element: T) -> R
): Map<K, R>
Semi related but the relationship between
aggregate
and
fold
for
Grouping
seems kind of fuzzy to me. It seems like this version of
fold
is just an awkward, two lambda version of aggregate. But then, the simplest case is handled most nicely by the
fold
overload taking a simple initial value. So the useful functionality is kind of spread between them, and yet aggregate is missing the most useful overload (IMHO). Just curious if there are reasons I'm missing why the API is this way. The first time I went to use
Grouping
it felt a bit clunkier than I'm used to in Kotlin.
t
actually,
fold
uses
aggregate
internally. So yes, it's kind of a two-lambda-version of
aggregate
that has an extra lambda defining how to initialize the accumulator if it didn't exist yet (and then still call the operation lambda, also on the first element). Personally I also find the
aggregate
syntax with the boolean flag a bit awkward, but I wouldn't like making the decision based on a
null
value either. Therefore I actually prefer the
fold
syntax
n
@Tobias Berger Deciding based on the null is actually really elegant though.
x.aggregate { k, a: R?, t -> (a ?: some_func(k, t)) +  t}
vs
x.fold( { k, t -> some_func(k, t) }) { k, a, t -> r + t }
kotlin tends to get less elegant with both multiple lambdas, and lambdas w/ multiple arguments (both noticeable contrasted to swift), and
fold
kind of puts both on full display. you spend a lot of verbiage declaring the lambda arguments repeatedly
t
you could do this though:
x.fold(::some_func) { k, a, t -> a + t }
but I guess it also depends on the case
n
fair enough