I’m wondering if there is something that works lik...
# announcements
j
I’m wondering if there is something that works like
zip
, but instead of returning pairs based on index, it returns pairs based on a predicate. For example:
Copy code
data class A(val id: String)
data class B(val id: String)

val listA: List<A> = listOf(A(“3”), A(“8”))
val listB: List<B> = listOf(B(“8”), B(“2”), B(“4”))

val pairs: List<Pair<A, B>> = listA.someTransformation(listB) { it.id == id }

// ‘pairs’ would contain:
// listOf((A("8"), B("8"))
Would love to know if there’s a best practice around this type of operation?
And to be clear, there could be several matching id’s between the lists (even though there’s only one in my example).
k
What do you want yo happen if there are multiple?
j
Oh sorry there will never be multiple matches in listB for a single item in listA. Ids would only appear once per list. When I said multiple, I meant like if listB had an additional element
B("3")
(matching the first element in listA)
Does that make sense?
And in my scenario, there’s more than one property in each data class that I’m matching them against (ruling out the simple “sort-then-zip” approach that would work in my hypothetical)
j
Like
intersect
that takes a block for the equality test.
Kinda.
j
Yea, kinda
k
Cartesian product + filter should do it, unfortunately there's no cartesian product in Kotlin, see https://youtrack.jetbrains.com/issue/KT-13012 and related issues. You'll have to write it yourself:
Copy code
listA.flatMap { a -> listB.map {  b -> a to b }.filter { (a, b) -> f(a,b) }
maybe with a
asSequence()
inbetween.
Another possibility:
Copy code
listA.flatMap { a -> listB.mapNotNull {  b -> if (f(a,b)) a to b else null } }
j
wow thanks @karelpeeters! let me try these and see if they do what i need
what is the
f
in the first one (i.e.
... f(a,b) }
?
j
a.id == b.id
j
oh i see
what do you mean by with a
asSequence()
in between?
a
listB.asSequence().map...
so that it doesn't actually create a B long list for each
a
which gets mostly `filter`ed out after it
j
for the first one, i get a type error in the filter on b
it thinks b is a Pair<A, B>, not B
j
Copy code
>>> listA.flatMap { a -> listB.map {  b -> a to b }.filter { (a, b) -> a.id == b.id }}
res45: kotlin.collections.List<kotlin.Pair<Line_10.A, Line_9.B>> = [(A(id=8), B(id=8))]
j
ah that works! (i was wrapping the predicate part in { }... still newish to kotlin). thank you both very much!
j
👍