Scala中可以使用map、foreach方法、for循环等多种方式遍历字符串,但是map应该是使用比较方便,比较多的,eg.
val upper = "Hello, Scala"
println(upper.map(_.toUpper))
println(upper.map(x => x.toUpper))
输出如下:
HELLO, SCALA
HELLO, SCALA
对于任何集合,如一个字符串中的一个字符序列也可以通过将集合方法连起来使用来达到目的。比方说在原始的String上面调用filter方法,创建一个新的字符串,删除字母“L”的所有小写字符。生成的字符调用map方法,便利其每个字符并将它们变成大写,eg.
println(upper.filter(_ != "l").map(_.toUpper))
println(upper.filter(_ != 'l').map(_.toUpper))
输出如下:
HELLO, SCALA
HEO, SCAA
使用for循环也可以达到遍历字符串的目的,eg.
for(c <- upper) println(c)
输出结果如下:
H
e
l
l
o
,
S
c
a
l
a
为了用for循环写出一个用起来像map的方法,在循环的结尾处加一个yield语句。eg.
println(for(c <- upper) yield c.toUpper)
输出如下:
HELLO, SCALA
在for循环中添加yield实际上是将每次循环的结果放到了一个临时存放区中。当循环结束时,在临时存放区中的所有元素以一个集合的形式返回。
println(for(c <- upper if c != 'l') yield c.toUpper)
输出如下:
HEO, SCAA
然而map方法或者for/yield这种方式都是将一个集合转换成为另一个新的集合,foreach则是典型的对每个元素进行操作但不返回结果的方法。对于打印来说这个很有用,eg:
upper.foreach(println)
输出如下:
H
e
l
l
o
,
S
c
a
l
a
理解map如何工作的
根据功能需要,可以给map方法传一个大的代码块。eg.
println(upper.map{c => (c.toByte + 1).toChar})
输出如下:
Ifmmp-!Tdbmb
map方法有一个隐式循环,在这个循环里,每次都会给算法传一个字符。具体map在TraversableLike.scala中的源码如下:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
def builder = { // extracted to keep method size under 35 bytes, so that it can be JIT-inlined
val b = bf(repr)
b.sizeHint(this)
b
}
val b = builder
for (x <- this) b += f(x)
b.result
}
注意到算法每次只操作一个字符。这是因为本例中的map方法是在String上调用的,所以map把String当做一个字符元素的序列集合来处理。为了保持代码整洁,可以把算法写成一个方法或者函数,这样就可以直接传给map了;eg.
val toLower = (c:Char) => (c.toByte + 32).toChar
println("HELLO".map(toLower))
输出如下:
hello
for/yield语法也可以达到同样的效果,eg.
println(for (c <- "HELLO") yield toLower(c))







网友评论