Last active
February 1, 2023 03:15
-
-
Save bastman/3f3821ebec89be58a9a1abf127b7adf3 to your computer and use it in GitHub Desktop.
kotlin: How to join 2 collections by a foreign key predicate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data class Off(val id: Int, val offName: String) | |
data class Prop(val id: Int, val propName: String, val offId: Int) | |
data class Joined(val off: Off, val props: List<Prop>) | |
fun main(args: Array<String>) { | |
val offs: List<Off> = listOf( | |
Off(id = 1, offName = "Off A"), | |
Off(id = 2, offName = "Off B") | |
) | |
val props: List<Prop> = listOf( | |
Prop(id = 101, propName = "prop A.101", offId = 1), | |
Prop(id = 102, propName = "prop A.102", offId = 1), | |
Prop(id = 201, propName = "prop B.201", offId = 2), | |
Prop(id = 301, propName = "prop C.201", offId = -100) | |
) | |
offs | |
.joinBy(props) { (off,prop) -> off.id == prop.offId } | |
// or use: .joinBy(props) { it.first.id == it.second.offId } | |
.map { Joined(off = it.first, props = it.second) } | |
.map { println(it) } | |
/* | |
prints: | |
Joined(off=Off(id=1, offName=Off A), props=[Prop(id=101, propName=prop A.101, offId=1), Prop(id=102, propName=prop A.102, offId=1)]) | |
Joined(off=Off(id=2, offName=Off B), props=[Prop(id=201, propName=prop B.201, offId=2)]) | |
*/ | |
} | |
private inline fun <T : Any, U : Any> List<T>.joinBy(collection: List<U>, filter: (Pair<T, U>) -> Boolean): List<Pair<T, List<U>>> = map { t -> | |
val filtered = collection.filter { filter(Pair(t, it)) } | |
Pair(t, filtered) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i would not call it join, its functionality is similar to C#'s https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.tolookup?view=netcore-3.1