如何使用声明式 Kotlin 在 2 个不同类型的列表之间复制 属性?
How to copy a property between 2 lists of different types using declarative Kotlin?
上下文
在 Kotlin 中使用声明式方法,需要将单个 name
属性 从 List
of User
对象复制到 List
of UserDetail
个对象基于匹配 id
个属性,如下所示:
val users = Arrays.asList(
User(1, "a"),
User(2, "b")
)
val details = Arrays.asList(
UserDetail(1),
UserDetail(2)
)
val detailsWithName = copyNameToUser(users, details)
型号是:
class User {
var id = -1;
var name = "" // given for all Users
constructor(id: Int, name: String)
// ...
}
class UserDetail {
var id = -1;
var name = "" // blank for all UserDetails
constructor(id: Int)
// ...
}
问题
尝试通过 forEach
可迭代函数使用声明式方法:
fun copyNameToDetails(users: List<User>, details: List<UserDetail>): List<UserDetail> {
details.forEach(d ->
users.forEach(u ->
if (d.id == u.id) {
d.name = u.name
}
)
)
return details
}
这可以在 Java 中实现,如下所示:
private static List<UserDetail> copyNameToDetails(List<User> users, List<UserDetail> details) {
for (UserDetail d: details) {
for (User u : users) {
if (d.id == u.id) {
d.name = u.name;
}
}
}
return details;
}
问题
如何使用声明式方法在 Kotlin 中完成此操作?
您对两个列表 (users.size * details.size
) 进行了太多次迭代,因此创建一个散列图可以稍微修复它:
fun copyNameToUsers(users: List<User>, details: List<UserDetail>): List<UserDetail> {
val usersById = users.associate { it.id to it }
details.forEach { d ->
usersById[d.id]?.let { d.name = it.name }
}
return details
}
另一种具有非可变值的方法:
data class User(val id: Int = -1, val name: String = "")
data class UserDetail(val id: Int = -1, val name: String = "")
private fun List<UserDetail>.copyNameToUser(users: List<User>): List<UserDetail> = map { userDetail ->
users.firstOrNull { userDetail.id == it.id }?.let { userDetail.copy(name = it.name) } ?: userDetail
}
上下文
在 Kotlin 中使用声明式方法,需要将单个 name
属性 从 List
of User
对象复制到 List
of UserDetail
个对象基于匹配 id
个属性,如下所示:
val users = Arrays.asList(
User(1, "a"),
User(2, "b")
)
val details = Arrays.asList(
UserDetail(1),
UserDetail(2)
)
val detailsWithName = copyNameToUser(users, details)
型号是:
class User {
var id = -1;
var name = "" // given for all Users
constructor(id: Int, name: String)
// ...
}
class UserDetail {
var id = -1;
var name = "" // blank for all UserDetails
constructor(id: Int)
// ...
}
问题
尝试通过 forEach
可迭代函数使用声明式方法:
fun copyNameToDetails(users: List<User>, details: List<UserDetail>): List<UserDetail> {
details.forEach(d ->
users.forEach(u ->
if (d.id == u.id) {
d.name = u.name
}
)
)
return details
}
这可以在 Java 中实现,如下所示:
private static List<UserDetail> copyNameToDetails(List<User> users, List<UserDetail> details) {
for (UserDetail d: details) {
for (User u : users) {
if (d.id == u.id) {
d.name = u.name;
}
}
}
return details;
}
问题
如何使用声明式方法在 Kotlin 中完成此操作?
您对两个列表 (users.size * details.size
) 进行了太多次迭代,因此创建一个散列图可以稍微修复它:
fun copyNameToUsers(users: List<User>, details: List<UserDetail>): List<UserDetail> {
val usersById = users.associate { it.id to it }
details.forEach { d ->
usersById[d.id]?.let { d.name = it.name }
}
return details
}
另一种具有非可变值的方法:
data class User(val id: Int = -1, val name: String = "")
data class UserDetail(val id: Int = -1, val name: String = "")
private fun List<UserDetail>.copyNameToUser(users: List<User>): List<UserDetail> = map { userDetail ->
users.firstOrNull { userDetail.id == it.id }?.let { userDetail.copy(name = it.name) } ?: userDetail
}