小编Nor*_*dyk的帖子

在Scala中基于类型的集合分区

给出以下数据模型:

sealed trait Fruit

case class Apple(id: Int, sweetness: Int) extends Fruit

case class Pear(id: Int, color: String) extends Fruit
Run Code Online (Sandbox Code Playgroud)

我一直在寻求实施一个隔离篮功能,对于给定的水果篮将返回单独的苹果和梨篮:

def segregateBasket(fruitBasket: Set[Fruit]): (Set[Apple], Set[Pear])

我尝试了几种方法,但它们似乎都没有完全适合这个法案.以下是我的尝试:

  def segregateBasket1(fruitBasket: Set[Fruit]): (Set[Apple], Set[Pear]) = fruitBasket
    .partition(_.isInstanceOf[Apple])
    .asInstanceOf[(Set[Apple], Set[Pear])]
Run Code Online (Sandbox Code Playgroud)

这是我发现的最简洁的解决方案,但是asInstanceOf如果我决定添加其他类型的水果,则会遭受明确的类型转换,并且将会很难延长.因此:

  def segregateBasket2(fruitBasket: Set[Fruit]): (Set[Apple], Set[Pear]) = {
    val mappedFruits = fruitBasket.groupBy(_.getClass)
    val appleSet = mappedFruits.getOrElse(classOf[Apple], Set()).asInstanceOf[Set[Apple]]
    val pearSet = mappedFruits.getOrElse(classOf[Pear], Set()).asInstanceOf[Set[Pear]]
    (appleSet, pearSet)
  }
Run Code Online (Sandbox Code Playgroud)

解决了额外水果类型的问题(扩展非常简单),但仍然强烈依赖于风险类型转换'asInstanceOf',我宁愿避免.因此:

  def segregateBasket3(fruitBasket: Set[Fruit]): (Set[Apple], Set[Pear]) = {
    val appleSet = collection.mutable.Set[Apple]()
    val pearSet = collection.mutable.Set[Pear]() …
Run Code Online (Sandbox Code Playgroud)

scala scala-collections shapeless

17
推荐指数
4
解决办法
1710
查看次数

标签 统计

scala ×1

scala-collections ×1

shapeless ×1