我对Scala中非常基本的东西感到难过。我正在研究“Atomic Scala”这本书。我不是一个完整的编程初学者,但我所拥有的经验是非常表面的。没有实际的开发经验,只需修补字符串操作和该级别的事情。
在本书中,其中一个练习(在参数化类型的一节中)是定义一个方法,该方法将矢量作为输入并将列表作为输出,其中列表的元素与矢量的元素相同。给定的向量可以是任意长度。
我不知道如果没有for循环并且不考虑列表(至少在开始时)是可变的,这样做的方法。
这是我试过的:
def explicit(v:Vector[Double]):List[Double] = {
var l = List()
for (i <- v) {
l = l :+ i
}
l
}
但似乎第四行出了问题。它会输出错误信息。
我有一种感觉,你可以做一些很酷的事情,如果你没有一个for循环,你只需要马上说“val l = List(~~~在这里用火箭或其他东西插入一些很酷的东西~~~)但是要么本书还没有涉及到这一点,或者我只是没想出来。
正如你所看到的,我在这里处于一个非常基础的层面,所以请尽力解释它,就像我五岁那样。 ;)
编辑补充说:我向前看了一下,看起来有几章后面我将学习“地图”方法,如果我准确地略读,将为这个问题提供一个解决方案。但那是后来的书。知道如何在没有地图的情况下完成它吗?
答案 0 :(得分:4)
List
是不可变的,“修改”List
实际上会产生List
的新实例。
map
在List
上是一个非常有用的功能,但对您没有帮助,它不会更改容器,只会更改包含的值。
我真的不明白你的练习要点,将Vector
变成List
就像在toList
上调用Vector
一样简单。
scala> val v= Vector(1,2,3)
v: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> v.toList
res0: List[Int] = List(1, 2, 3)
在第一条评论后编辑:是的,简单地调用toList
进行练习是没有意义的。难以真正知道预期的内容,本章/部分的主要内容是什么?
另一种方式是:List(Vector(1,2,3):_*)
。 @Rex Kerr答案也很好。
答案 1 :(得分:1)
看起来更像是递归和/或类型参数的练习:
def parameterized[T](v: Vector[T]): List[T] = v match {
case head +: tail => head :: parameterized(tail)
case _ => Nil
}
def parameterized[T](v: Vector[T]): List[T] = {
def toList[T](v: Vector[T], l: List[T]): List[T] = v match {
case init :+ last => toList(init, last :: l)
case _ => l
}
toList(v, Nil)
}
答案 2 :(得分:0)
首先,您现有的代码不起作用,因为var l = List()
会创建一个Nothing
类型的空列表。这有点意义,因为其中没有任何东西,但是当你想要放入某些东西时,它就不能很好地工作。这样做:
var l = List[Double]()
但这仍然不是一个很好的方法,因为每次添加到列表的末尾都需要重建整个前面的部分!但是,添加到头部并不需要任何重建,因此如果可以的话,您确实需要以相反的顺序添加元素。对于Vector
,事实证明在这样的上下文中以相反顺序前进的最佳方式是reverseIterator
。所以
for (i <- v.reverseIterator) l = i :: l
这仍然不是最好的做事方式,除非它只是一个练习,因为Vector
有一个toList
方法,这显然是明显的。