将 Scala Iterable[T] 转换为 Option[Iterable[S]],如果所有 T 都是 S 的实例则填充?
Converting a Scala Iterable[T] to an Option[Iterable[S]], populated if ALL the T are instances of S?
我有一种模糊的感觉,这种方法可能存在(可能在 Cats 中?)-目的是将 Iterable[T]
( 或 Set[T]
是我真正感兴趣的 ) 到 Option[Iterable[S]]
- 结果是:
Some[Iterable[S]]
: 如果 all 条目在 Iterable[T]
是 S
的实例
None
:如果 Iterable[T]
中的任何条目不是 S
的实例
我知道猫中已经有一种类似的方法,由 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
不是 setOfT
的实例S
:
val setOfT: Set[T] = ???
val setOfS: Set[S] = setOfT.collect {case s: S => s}
正如 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
}
...很高兴看到更好的实现!
考虑无形类型安全转换
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]]
。
我有一种模糊的感觉,这种方法可能存在(可能在 Cats 中?)-目的是将 Iterable[T]
( 或 Set[T]
是我真正感兴趣的 ) 到 Option[Iterable[S]]
- 结果是:
Some[Iterable[S]]
: 如果 all 条目在Iterable[T]
是S
的实例
None
:如果Iterable[T]
中的任何条目不是S
的实例
我知道猫中已经有一种类似的方法,由 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
不是 setOfT
的实例S
:
val setOfT: Set[T] = ???
val setOfS: Set[S] = setOfT.collect {case s: S => s}
正如 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
}
...很高兴看到更好的实现!
考虑无形类型安全转换
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]]
。