在kotlin中以有效的方式查找第一次出现的索引值



嘿,我有一个嵌套列表,我想找到第一次出现的索引值。

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 }

如果你想坚持函数式风格,那么你可以这样做:

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条目,我们得到了附在它上面的outerinner

asSequence()在这两个地方改变了它内部的工作方式。序列是懒惰的,这意味着它们只在需要时执行计算,并且在进入另一个项目之前尝试处理单个项目。如果没有asSequence(),我们将首先创建一个包含所有xyz项的完整列表,如上面的示例所示。然后,如果xyz2是我们搜索的,那就意味着我们浪费了时间来处理xyz3,xyz4xyz5,因为我们对它们不感兴趣。

对于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
}

在Kotlin中,您可以使用indexOf()函数返回给定元素第一次出现的索引,如果数组不包含该元素,则使用-1函数。

的例子:

fun findIndex(arr: Array<Int>, item: Int): Int {
return arr.indexOf(item)
}

相关内容

  • 没有找到相关文章

最新更新