首页 > 解决方案 > Scala:从“任何”值的集合中检测并提取更具体的东西

问题描述

AnyScala:从一组值中检测和提取更具体的东西。

(动机:Saddle 库——我发现的唯一一个提供 Frame 类型的 Scala 库,这对数据科学至关重要——让我遇到了这个难题。有关详细信息,请参阅最后一节。)

问题

c想象一下type的集合C[Any]。假设 的某些元素属于比 严格更具体c的类型。TAny

我想要一种方法来查找所有类型的元素,T然后创建一个d类型的对象C[T],而不是C[Any].

一些演示问题的代码

scala> val c  = List(0,1,"2","3")
<console>:11: warning: a type was inferred to be `Any`;
this may indicate a programming error.
       val c  = List(0,1,"2","3")
                ^
c: List[Any] = List(0, 1, 2, 3)

scala> :t c(0)
Any // I wish this were more specific

// Scala can convert some elements to Int.
scala> val c0 = c(0) . asInstanceOf[Int]
c0: Int = 0
// But how would I detect which?

scala> val d = c.slice(0,2)
d: List[Any] = List(0, 1) // I wish this were List[Int]

动机:为什么 Saddle 库会导致我遇到这个问题

Saddle 可让您操纵“框架”(表格)。框架可以有各种类型的列。一些系统(例如 Pandas)为每一列分配一个单独的类型。然而,Saddle 中的每一帧都恰好有三个类型参数:行标签的类型、列标签的类型和单元格的类型。

现实世界的数据通常是字符串和数字的混合体。此类表格在 Saddle 中的表示方式是作为单元格类型为 Any 的 Frame。我想向下转换(向上转换?多态性很难)一列比一系列 Any 值更具体的东西。我还希望能够测试一个专栏,以确保演员表是合适的。

在 Saddle 的 Github 网站上发布了一个关于这个谜题的问题。

标签: scalagenericspolymorphismsaddle

解决方案


你可以做这样的事情

scala> val c  = List(0,1,"2","3")
c: List[Any] = List(0, 1, 2, 3)
scala> c.collect { case x: Int => x; case s: String => s.toInt  }
res0: List[Int] = List(0, 1, 2, 3)

如果您只想要Int类型,您可以简单地删除第二种情况。


推荐阅读