给出以下数据模型:
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)