我正在尝试将我的嵌套for循环转换为Kotlin中的asSequence
。在这里,我的目标是使用相同的密钥从另一个对象数组获取并更新所有对象数组的值。
嵌套for循环:
val myFields = getMyFields()
val otherFields = getOtherFields()
for (myField in myFields) { // loop tru the my fields
for (otherField in otherFields) { // find the same fields
if (myField.key == otherField.key) { // if the same, update the value
val updatedMyField = myField.copy(value = otherValue.value)
myFields[myFields.indexOf(myField)] = updatedMyField // update my field value
break
}
}
}
我尝试过的:
val updatedMyFields = getMyFields().asSequence()
.map { myField ->
getOtherFields().asSequence()
.map { otherField ->
if (myField.key == otherField.key) {
return@map otherField.value
} else {
return@map ""
}
}
.filter { it?.isNotEmpty() == true }
.first()?.map { myField.copy(value = it.toString()) }
}
.toList()
但这不会编译,因为它将返回List<List<MyField>>
。
我只是在寻找更清洁的东西。
正如评论所表明的那样,使用Map
可能会更有效率。
(更准确地说,地图解决方案需要的时间与列表长度的总和成正比,而嵌套的for循环需要与其产品成比例的时间 - 这会更快地变大。)
这是一种方法:
val otherFields = getOtherFields().associate{ it.key to it.value }
val myFields = getMyFields().map {
val otherValue = otherFields[it.key]
if (otherValue != null) it.copy(value = otherValue) else it
}
第一行从“其他字段”键创建一个Map
到它们的值。然后其余部分使用它从“我的字段”创建一个新列表,替换当前存在的“其他字段”中的值。
我不得不对类型和c做出假设,因为问题中的代码不完整,但这应该做同样的事情。显然,你可以通过修改it.copy()
来改变它合并值的方式。
根据周围的代码,可能会有更简单,更有效的方法。如果你将它扩展为Minimal, Complete, and Verifiable Example - 特别是,根据你的评论说明你已经如何使用Map
的那个 - 我们可能能够提出更好的建议。
为什么要使用asSequence()?你可以去做那样的事情:
val myFields = getMyFields()
val otherFields = getOtherFields()
myFields.forEach{firstField ->
otherFields.forEach{secondField ->
if (firstField.key == secondField.key) {
myFields[myFields.indexOf(firstField)] = secondField.value
}
}
}
这将比嵌套的for循环完成相同的工作,并且比嵌套的asSequence()更容易阅读,理解和维护。