嘿,我有嵌套串列,我想找到第一個出現的索引值。
data class ABC(
val key: Int,
val value: MutableList<XYZ?>
)
data class XYZ)
val isRead: Boolean? = null,
val id: String? = null
)
我添加了查找 XYZ 物件的代碼,但我需要找到索引。那么我如何才能以有效的方式實作。如何改進我的代碼?
list?.flatMap { list ->
list.value
}?.firstOrNull { it?.isRead == false }
uj5u.com熱心網友回復:
如果你想堅持功能風格,那么你可以這樣做:
val result = list.asSequence()
.flatMapIndexed { outer, abc ->
abc.value.asSequence()
.mapIndexed { inner, xyz -> Triple(outer, inner, xyz) }
}
.find { it.third?.isRead == false }
if (result != null) {
val (outer, inner) = result
println("Outer: $outer, inner: $inner")
}
對于每一個ABC專案,我們記得它作為指標outer,我們映射/變換其串列XYZ項為元組的串列:(outer, inner, xyz)。然后flatMap將所有此類串列(我們每個ABC專案有一個串列)合并為一個單一的(outer, inner, xyz).
換句話說,整個flatMapIndexed()塊改變了這個(偽代碼):
[ABC([xyz1, xyz2]), ABC([xyz3, xyz4, xyz5])]
進入這個:
[
(0, 0, xyz1),
(0, 1, xyz2),
(1, 0, xyz3),
(1, 1, xyz4),
(1, 2, xyz5),
]
然后我們使用find()搜索特定的xyz專案,我們獲得outer并inner連接到它。
asSequence()這兩個地方都改變了它內部的作業方式。序列是惰性的,這意味著它們僅根據需要執行計算,并且在轉到另一個專案之前嘗試處理單個專案。如果沒有,asSequence()我們將首先創建一個所有xyz專案的完整串列,如上例所示。然后,如果xyz2是我們搜索的那個,那將意味著我們在處理xyz3,xyz4和上浪費了時間xyz5,因為我們對它們不感興趣。
隨著asSequence()我們從來沒有真正建立這個平面串列,而是每個專案執行的所有操作。find()要求檢查下一個專案,mapIndexed僅映射單個專案,flatMapIndexed也僅映射此單個專案,如果find()成功,則不處理其余專案。
在大多數情況下,在這里使用序列可以大大提高性能。在某些情況下,例如當串列很小時,序列可能會通過增加開銷來降低性能。但是,差異非常小,因此最好保持原樣。
正如我們所見,在這種情況下,函式式風格可能會非常復雜。使用命令式風格和好的舊回圈可能是一個更好的主意:
list.indicesOfFirstXyzOrNull { it?.isRead == false }
inline fun Iterable<ABC>.indicesOfFirstXyzOrNull(predicate: (XYZ?) -> Boolean): Pair<Int, Int>? {
forEachIndexed { outer, abc ->
abc.value.forEachIndexed { inner, xyz ->
if (predicate(xyz)) {
return outer to inner
}
}
}
return null
}
uj5u.com熱心網友回復:
在 Kotlin 中,您可以使用indexOf()回傳給定元素第一次出現的索引的函式,或者-1如果陣列不包含該元素。
例子:
fun findIndex(arr: Array<Int>, item: Int): Int {
return arr.indexOf(item)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/324544.html
