我有一个包含不同类型元素的初始列表,我必须对其进行过滤以仅采用int和double值。
例如(1 :: "hello" :: 100 :: 3.14 :: ('a'::10::Nil) :: 'c' :: (5,7,'a') :: Nil)
应该变成(1, 100, 3.14, List(10), (5,7))
我想出一个解决方案很麻烦,因为一旦将列表传递给方法,它就变成了List [Any]类型的列表,在转换之前我需要知道每个元素的类型。它不包含其他子结构(例如元组),这不是问题,因为我可以通过模式匹配来管理某些事情。
是否可以通过某种方式获取Any元素的特定类型并将其强制转换?
答案 0 :(得分:2)
作为学术活动,这很愚蠢。您应该学习如何避免这种情况,而不是尝试应对。尽管如此,错误的代码有时还是很有启发性的。
def intOrDbl(la :List[Any]) :List[Any] = la.flatMap{
case i:Int => List(i)
case d:Double => List(d)
case l:List[_] => List(intOrDbl(l))
case t:Product => val res = intOrDbl(t.productIterator.toList)
res.length match {
case 0 => Nil
case 1 => List(res)
case 2 => List((res(0),res(1)))
case 3 => List((res(0),res(1),res(2)))
case 4 => List((res(0),res(1),res(2),res(3)))
// etc.
}
case _ => Nil
}
val data = 1 :: "hello" :: 100 :: 3.14 :: ('a'::10::Nil) :: 'c' :: (5,7,'a') :: Nil
intOrDbl(data)
//res0: List[Any] = List(1, 100, 3.14, List(10), (5,7))
答案 1 :(得分:1)
您可以选择的一种方法是将结果类型放入ADT中。这是可能的工作方式:
sealed trait IntOrDoubleOrList
case class IntValue(value: Int) extends IntOrDoubleOrList
case class DoubleValue(value: Double) extends IntOrDoubleOrList
case class ListValue(value: List[IntOrDoubleOrList]) extends IntOrDoubleOrList
def filterIntOrDouble(l: List[_]): List[IntOrDoubleOrList] = {
l.collect({
case iv: Int => IntValue(iv)
case dv: Double => DoubleValue(dv)
case lv: List[_] => ListValue(filterIntOrDouble(lv))
})
}
def test(): Unit = {
val origList = (1 :: "hello" :: 100 :: 3.14 :: ('a' :: 10 :: Nil) :: 'c' :: (5, 7, 'a') :: Nil)
val f = filterIntOrDouble(origList)
println(f)
}
根据您的进一步需求,您可以使用IntOrDoubleOrList
之类的一些辅助方法来扩展foreach(intHandler: Int => Unit, doubleHandler: Double => Unit)
性状