如何在 Kotlin 中对列表进行分区和类型转换
How to partition and typecast a List in Kotlin
在 Kotlin 中我可以:
val (specificMembers, regularMembers) = members.partition {it is SpecificMember}
但是据我所知我不能做类似的事情:
val (specificMembers as List<SpecificMember>, regularMembers) = members.partition {it is SpecificMember}
我的问题是 - 是否有一种惯用的方法可以按 class 对可迭代对象进行分区,并在需要时对这些分区的部分进行类型转换。
partition
函数将 return 一个 Pair<List<T>, List<T>>
,其中 T
是您的 Iterable
的通用类型。您可以使用例如再次转换分区值let
:
val (specificMembers, regularMembers) = lists
.partition { it is SpecificMember }
.let { Pair(it.first as List<SpecificMember>, it.second) }
如果您更频繁地需要该功能,您可以根据需要重新实现实际的 partition
,例如:
inline fun <reified U : T, T> Iterable<T>.partitionByType(): Pair<List<U>, List<T>> {
val first = ArrayList<U>()
val second = ArrayList<T>()
for (element in this) {
if (element is U) first.add(element)
else second.add(element)
}
return Pair(first, second)
}
用法类似如下:
val (specificMembers, regularMembers) = members.partitionByType<SpecificMember, Member>()
// where specificMembers : List<SpecificMember>
// and regularMembers : List<Member> for this example
请注意,通过这种方式您还可以将第二种类型设置为更通用的类型。这是否有意义,我把它留给你。至少这样 unchecked cast 不是必需的。
Simon 还通过 let
用法展示了替代方案。您也可以直接将 partition
的结果(没有 let
和另一个 Pair
)转换为任何合适的结果,例如:
val (specificMembers, regularMembers) = members.partition {it is SpecificMember} as Pair<List<SpecificMember>, List<Member>>
在 Kotlin 中我可以:
val (specificMembers, regularMembers) = members.partition {it is SpecificMember}
但是据我所知我不能做类似的事情:
val (specificMembers as List<SpecificMember>, regularMembers) = members.partition {it is SpecificMember}
我的问题是 - 是否有一种惯用的方法可以按 class 对可迭代对象进行分区,并在需要时对这些分区的部分进行类型转换。
partition
函数将 return 一个 Pair<List<T>, List<T>>
,其中 T
是您的 Iterable
的通用类型。您可以使用例如再次转换分区值let
:
val (specificMembers, regularMembers) = lists
.partition { it is SpecificMember }
.let { Pair(it.first as List<SpecificMember>, it.second) }
如果您更频繁地需要该功能,您可以根据需要重新实现实际的 partition
,例如:
inline fun <reified U : T, T> Iterable<T>.partitionByType(): Pair<List<U>, List<T>> {
val first = ArrayList<U>()
val second = ArrayList<T>()
for (element in this) {
if (element is U) first.add(element)
else second.add(element)
}
return Pair(first, second)
}
用法类似如下:
val (specificMembers, regularMembers) = members.partitionByType<SpecificMember, Member>()
// where specificMembers : List<SpecificMember>
// and regularMembers : List<Member> for this example
请注意,通过这种方式您还可以将第二种类型设置为更通用的类型。这是否有意义,我把它留给你。至少这样 unchecked cast 不是必需的。
Simon 还通过 let
用法展示了替代方案。您也可以直接将 partition
的结果(没有 let
和另一个 Pair
)转换为任何合适的结果,例如:
val (specificMembers, regularMembers) = members.partition {it is SpecificMember} as Pair<List<SpecificMember>, List<Member>>