我能找到的最接近的東西是 zip,它幾乎可以滿足我的需求,但它使用索引。我想指定一個欄位,如果兩個串列的值相同,則在該欄位上加入。
在 SQL 中,將使用“table1 INNER JOIN table2 WHERE table1.field = table2.field”。Kotlin 中有類似的東西嗎?
也許這個例子更清楚:
class Something(val id : Int, val value : Int)
val list1 = listOf(Something(0, 1), Something(1, 6), Something(2, 8))
val list2 = listOf(Something(1, 2), Something(5, 3), Something(9, 6))
val result = list1.innerJoin(list2, on=id).map { element1, element2 -> element1.value * element2.value}
//should return [12] (6*2)
list1 和 list2 都有一個 id=1 的元素,所以在這個例子中它們的值(6 和 2)相乘,結果應該是 12。
目前我使用這個代碼片段,它有效,但我想知道是否有更簡單和更有效的方法來做到這一點。
val result = list1.map { element1 ->
val element2 = list2.find { element2 -> element2.id == element1.id } ?: return@map null
element1.value * element2.value
}.filterNotNull()
謝謝。
uj5u.com熱心網友回復:
您可以使用它mapNotNull來消除二次過濾步驟,但這將盡可能簡潔。您也可以list2先轉換為 Map 以將其從O(n^2)更改為O(n)。
val list2ById = list2.associateBy(Something::id)
val result = list1.mapNotNull { element1 ->
list2ById[element1.id]?.value?.times(element1.value)
}
uj5u.com熱心網友回復:
Kotlin 沒有為此提供 stdlib 方法,但您可以定義自己的:
fun <T> Collection<T>.innerJoin(other: Collection<T>, on: T.() -> Any): Collection<Pair<T, T>> {
val otherByKey = other.associateBy(on)
return this.mapNotNull {
val otherMapped = otherByKey[on(it)]
if (otherMapped == null) null else it to otherMapped
}
}
用法:
fun main() {
val list1 = listOf(Something(0, 1), Something(1, 6), Something(2, 8))
val list2 = listOf(Something(1, 2), Something(5, 3), Something(9, 6))
val result = list1.innerJoin(list2, on = { id }).map { (element1, element2) -> element1.value * element2.value }
println(result) //12
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/440826.html
上一篇:kotlin獲取類屬性的靜態型別
下一篇:Flutter/Android:您上傳的APK具有活動[...]但沒有'android:exported'屬性。出口=“真”不作業
