【问题标题】:How to partition and typecast a List in Kotlin如何在 Kotlin 中对列表进行分区和类型转换
【发布时间】:2019-05-27 20:30:04
【问题描述】:

在 Kotlin 中我可以:

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

但据我所知,我不能这样做:

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

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

【问题讨论】:

    标签: kotlin casting partitioning


    【解决方案1】:

    如果您更频繁地需要该功能,您可以根据需要重新实现实际的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-usage 显示了替代方案。您也可以直接将partition(没有let 和另一个Pair)的结果转换为任何合适的值,例如:

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

    【讨论】:

      【解决方案2】:

      partition 函数将返回一个Pair&lt;List&lt;T&gt;, List&lt;T&gt;&gt;,其中TIterable 的泛型类型。您可以使用例如再次转换分区值let:

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

      【讨论】:

      • b 的 'a` 和创建 Pair 的惯用方式吗?
      • 随你喜欢。 to 函数是少数几个可用的标准中缀函数之一,也是经常使用的函数
      • 由于这不是很重要,所以我将其更改为实际的构造函数
      • 但这引入了未经检查的演员表:(
      猜你喜欢
      • 2017-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多