How to extend a Scala list to enable slicing not by explicit position but by given predicate/condition

后端 未结 3 1469
有刺的猬
有刺的猬 2020-11-28 16:41

For

trait Item
case class TypeA(i: Int) extends Item
case class TypeB(i: Int) extends Item

consider a Scala list of items such as

3条回答
  •  死守一世寂寞
    2020-11-28 17:30

    Aren't you looking for filter, which works (almost) without any tweaks for your examples?

    $ sbt console
    scala> trait Item
    scala> case class TypeA(i: Int) extends Item
    scala> case class TypeB(i: Int) extends Item
    scala> val myList = List(TypeA(1), TypeB(11), TypeB(12), 
                             TypeA(2), TypeB(21), 
                             TypeA(3), TypeB(31))
    myList: List[Product with Serializable with Item] = List(TypeA(1), TypeB(11), TypeB(12), TypeA(2), TypeB(21), TypeA(3), TypeB(31))
    

    your first works unaltered:

    scala> myList.filter { x => x.isInstanceOf[TypeA] }
    res0: List[Product with Serializable with Item] = List(TypeA(1), TypeA(2), TypeA(3))
    

    your second requires a default case:

    scala> myList.filter { case TypeA(x) => x < 10; case _ => false }
    res2: List[Product with Serializable with Item] = List(TypeA(1(3))
    

    See also collect, which takes a partial function instead of a boolean predicate:

    scala> myList.collect { case z @ TypeA(x) if x < 10 => z }
    res3: List[TypeA] = List(TypeA(1), TypeA(2), TypeA(3))
    

    and can transform as well:

    scala> myList.collect { case TypeA(x) if x < 10 => x }
    res4: List[Int] = List(1, 2, 3)
    

提交回复
热议问题