Kev
01/19/2024, 7:08 AMYoussef Shoaib [MOD]
01/19/2024, 7:38 AMassociateBy on one of them, then a map on the other, pairing it with the matching value from the first onesimon.vergauwen
01/19/2024, 10:40 AMinline fun <A, B, C, Key> Iterable<A>.zipBy(
other: Iterable<B>,
keySelectorA: (A) -> Key,
keySelectorB: (B) -> Key,
combine: (A, B) -> C
): List<C> {
val firstByKey = associateBy(keySelector)
val secondByKey = other.associateBy(keySelector)
return (firstByKey.keys intersect secondByKey.keys)
.map { key -> firstByKey.getValue(it) to secondByKey.getValue(it) }
}
• intersect creates a Set of all common Key
• getValue returns the value for Key, (and throws NoSuchKeyElementException but that is impossible in this case)
• keySelector maps A and B to Key, in your case id field
• combine allows to transform common value to be transformed in your case ::Pair.simon.vergauwen
01/19/2024, 10:42 AMYoussef Shoaib [MOD]
01/19/2024, 10:45 AMassociateBy on one and iterate over the other with mapNotNull, but I think it's likely an unnecessary optimizatuonsimon.vergauwen
01/19/2024, 10:54 AMpublic inline fun <A, B, C, Key> Iterable<A>.zipBy(
other: Iterable<B>,
keySelectorA: (A) -> Key,
keySelectorB: (B) -> Key,
combine: (A, B) -> C
): List<C> {
val aByKey = associateBy(keySelectorA)
return other.mapNotNull { b ->
val key = keySelectorB(b)
val aOrNull = aByKey[key]
aOrNull?.let { a -> combine(a, b) }
}
}