如何解决将 Scala Iterable[T] 转换为 Option[Iterable[S]],如果所有 T 都是 S 的实例,则填充?
我有一种模糊的感觉,这样的方法可能存在(可能在 Cats 中?) - 目的是将 Iterable[T]
( 或 Set[T]
'm 实际上对) 感兴趣到 Option[Iterable[S]]
- 结果是:
我知道 Cats 中已经有一种类似的方法,由 Alternative
授予 - 它是 separate
:
import cats.implicits._
import alleycats.std.set._
val stringsAndInts: Set[Either[String,Int]] = Set(Right(6),Left("Foo"))
val (strings: Set[String],ints: Set[Int]) = stringsAndInts.separate
...这对 Set[Either[A,B]
很有效 - 但对于这个问题,我只对任何旧的 Set[T]
感兴趣。
collect
怎么样?
这段使用 Scala 标准库方法 collect
的代码将编译 - 但请注意,它总是会产生一个 Set[S]
- 即使某些 setofT
不是 {{ 1}}:
S
解决方法
考虑不定形类型安全转换
import shapeless._
import syntax.typeable._
val xs: Set[Any] = Set("picard","worf")
xs.cast[Set[Int]]
// res1: Option[Set[Int]] = None
xs.cast[Set[String]]
// res2: Option[Set[String]] = Some(value = Set("picard","worf"))
如果您希望获得与 collect
类似的功能并且已经在类路径上有猫,那么这里是单行
import alleycats.std.set._
animals.map(implicitly[ClassTag[Dog]].unapply).sequence
Option[Set[Dog]]
的类型。
正如 Luis Miguel Mejía Suárez 在评论中指出的那样,由于类型擦除,我想要的方法不可能用于任意类型。
最后,我写了这样的代码:
val animals: Set[Animal] = ???
val optDogs: Option[Set[Dog]] = animals.foldLeft(Option(Set.empty[Dog])) {
case (oDogs,dog: Dog) => oDogs.map(_ + dog)
case _ => None
}
...不过很高兴看到更好的实现!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。