如何在Kotlin中对列表进行分区和类型转换

时间:2019-05-27 11:41:30

标签: kotlin casting partitioning

在Kotlin中,我可以:

val (specificMembers, regularMembers) = members.partition {it is SpecificMember}

据我所知,我不能做类似的事情:

val (specificMembers as List<SpecificMember>, regularMembers) = members.partition {it is SpecificMember}

我的问题是-是否有一种惯用的方法来按类对iterable进行分区,并在需要时将这些已分区的部分类型转换。

2 个答案:

答案 0 :(得分:2)

partition函数将返回Pair<List<T>, List<T>>,其中TIterable的通用类型。您可以使用来再次转换分区值let

val (specificMembers, regularMembers) = lists
    .partition { it is SpecificMember }
    .let { Pair(it.first as List<SpecificMember>, it.second) }

答案 1 :(得分:2)

如果您更频繁地需要该功能,则可以根据需要重新实现实际的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>>