I don't see why filter
does not work for you:
scala> trait TraitA { def propX: String }; trait TraitB { def abc: Int }
defined trait TraitA
defined trait TraitB
scala> class A extends TraitA { def propX = util.Random.nextInt(5).toString() }
defined class A
scala> class B extends A with TraitB { def abc = util.Random.nextInt(5) }
defined class B
scala> val xs: List[TraitA] = List.fill(15)(if (util.Random.nextBoolean()) new A else new B)
xs: List[TraitA] = List(A@6b46e91a, B@7c71e0fb, A@1869be91, B@465e2e1c, B@5125545b, A@69c54bfb, B@17ff81fd, A@7af155a, B@77a2cba6, A@60e83ca6, A@2ee5e7fe, B@77e1ecbf, A@117e2d16, A@72c20852, B@20b07a5a)
scala> xs collect { case a: TraitB => a } groupBy (_.propX)
res7: scala.collection.immutable.Map[String,List[TraitA with TraitB]] = Map(4 -> List(B@465e2e1c, B@77e1ecbf), 1 -> List(B@77a2cba6), 0 -> List(B@20b07a5a), 2 -> List(B@7c71e0fb, B@17ff81fd), 3 -> List(B@5125545b))
Even if you loose visibility, you can always do a pattern match with something like { case a: TraitA with TraitB => }
.