scala 字符串转数组
前言
这是计划中的针对初学者的Scala编程系列教程的第二部分,具体参考了我2011年秋季的课程《计算语言学入门》。 您可以在此博客上查看其他教程。 它们也列在课程的链接页面上。
本教程重点介绍元组和列表,这是用于处理元素组的两种构造。 没有后者,您将无法完成很多工作,而前者是如此有用,您可能会发现自己经常使用它们。
元组
在上一教程中,我们看到了如何将单个值分配给变量,然后在各种上下文中使用。 元组是该值的概括:两个,三个,四个和更多值的集合。 每个值可以有自己的类型。
scala> val twoInts = (3,9)
twoInts: (Int, Int) = (3,9)
scala> val twoStrings = ("hello", "world")
twoStrings: (java.lang.String, java.lang.String) = (hello,world)
scala> val threeDoubles = (3.14, 11.29, 1.5)
threeDoubles: (Double, Double, Double) = (3.14,11.29,1.5)
scala> val intAndString = (7, "lucky number")
intAndString: (Int, java.lang.String) = (7,lucky number)
scala> val mixedUp = (1, "hello", 1.16)
mixedUp: (Int, java.lang.String, Double) = (1,hello,1.16)
元组的元素可以通过几种不同的方式进行恢复。 一种方法是在初始化某些变量时使用元组,每个变量取等号右侧元组中相应位置的值。
scala> val (first, second) = twoInts
first: Int = 3
second: Int = 9
scala> val (numTimes, thingToSay, price) = mixedUp
numTimes: Int = 1
thingToSay: java.lang.String = hello
price: Double = 1.16
Scala剥离这些值,并将其分配给每个单个变量。 这在返回元组的函数的上下文中非常有用。 例如,考虑一个函数,当您为其提供范围的中点以及该点的每一侧的间隔大小时,它会提供范围的左边缘和右边缘。
scala> def rangeAround(midpoint: Int, size: Int) = (midpoint - size, midpoint + size)
rangeAround: (midpoint: Int, size: Int)(Int, Int)
由于rangeAround返回一个元组(特别是对),因此我们可以调用它并直接从函数调用中为左右设置变量。
scala> val (left, right) = rangeAround(21, 3)
left: Int = 18
right: Int = 24
访问元组中的值的另一种方法是通过索引,使用“ _n ”,其中n是所需项目的索引。
scala> print(mixedUp._1)
1
scala> print(mixedUp._2)
hello
scala> print(mixedUp._3)
1.16
语法有点奇怪,但是您会习惯的。
元组是编程语言中非常有用的功能。 随着我们的前进,您将看到一些有关其实用程序的示例。
清单
列表是所有购物者都熟悉的订购商品的集合。 元组显然与列表相关,但是它们的通用性较差,因为它们必须在单个语句中创建,它们的长度是有限的(大约20左右),并且不支持对所有元素执行计算的运算。
在Scala中,我们可以创建字符串,整数和双精度(及更多)列表。
scala> val groceryList = List("apples", "milk", "butter")
groceryList: List[java.lang.String] = List(apples, milk, butter)
scala> val odds = List(1,3,5,7,9)
odds: List[Int] = List(1, 3, 5, 7, 9)
scala> val multinomial = List(.2, .4, .15, .25)
multinomial: List[Double] = List(0.2, 0.4, 0.15, 0.25)
我们看到Scala响应已创建一个List,并在其中包含的元素类型周围加上了括号。 因此, List [Int]被读为“一个整数列表”,依此类推。 这就是说List是一个参数化的数据结构:它是一个保存特定类型元素的容器。 我们将了解如何通过不同类型参数化Lists来执行不同的操作。
我们还可以创建混合类型的列表。
scala> val intsAndDoubles = List(1, 1.5, 2, 2.5)
intsAndDoubles: List[Double] = List(1.0, 1.5, 2.0, 2.5)
scala> val today = List("August", 23, 2011)
today: List[Any] = List(August, 23, 2011)
类型有时会自动转换,例如将intsAndDoubles的 Ints转换为Doubles,但通常没有明显的可泛化类型。 例如, 今天是一个List [Any] ,这意味着它是一个Anys列表-Any是Scala中最通用的类型,它是所有类型的超类型。 就像在说:“是的,我有一个清单……嗯,你知道……东西。”
列表还可以包含列表(以及列表列表,以及列表列表…)。
scala> val embedded = List(List(1,2,3), List(10,30,50), List(200,400), List(1000))
embedded: List[List[Int]] = List(List(1, 2, 3), List(10, 30, 50), List(200, 400), List(1000))
嵌入的类型为List [List [Int]] ,您可以将其读取为“ Int列表的列表”。
清单方法
好的,现在我们有了一些列表,我们该如何处理? 实际上很多。 列表的最基本属性之一是它的长度,您可以通过在引用该列表的变量之后使用“ .length ”来获得它的长度。
scala> groceryList.length
res19: Int = 3
scala> odds.length
res20: Int = 5
scala> embedded.length
res21: Int = 4
请注意, 嵌入的长度为4,这是它包含的列表的数量(不是这些列表中元素的数量)。
变量variable.method表示您正在根据该变量的值调用特定于该变量类型的函数。 好吧,那是一口。 Scala是一种面向对象的语言,这意味着每个值都有一组随之而来的动作。 可用的操作取决于其类型。 因此,在上面,我们在上面给出的每个列表值上调用了List可用的length方法。 您在上一教程中没有意识到这一点,但是您在添加Ints或串联字符串时使用的是方法–只是Scala允许我们不用“”。 和在某些情况下的paretheses。 如果我们不放下它们,这就是它的样子。
scala> 2.+(3)
res25: Double = 5.0
scala> "Portis".+("head")
res26: java.lang.String = Portishead
发生的情况是,整数有一个称为“ + ”的方法,而字符串有一个称为“ + ”的不同方法。 他们本来可以被称为“账单”和“鲍勃”,但除其他外,这将更难以记住。 整数还具有字符串没有的其他方法,例如“ – ”,“ * ”和“ / ”。 (注意:我现在返回省略“。”和paretheses。)
scala> 5-3
res27: Int = 2
scala> "walked" - "ed"
<console>:8: error: value - is not a member of java.lang.String
"walked" - "ed"
Scala抱怨我们试图在String上使用“ – ”方法,因为String没有这种方法。 另一方面,Ints没有称为length的方法,而Strings有。
scala> 5.length
<console>:8: error: value length is not a member of Int
5.length
^
scala> "walked".length
res31: Int = 6
对于字符串, length返回字符数,而对于列表, length是元素数。 字符串长度方法本可以称为“ numberOfCharacters”,但是“长度”更容易记住,它使我们可以像对待其他序列一样对待字符串,并以类似的方式考虑它们。
让我们回到列表以及我们可以使用它们做什么。 两个列表的“加法”是它们的串联,并以“ ++ ”表示。
scala> val evens = List(2,4,6,8)
evens: List[Int] = List(2, 4, 6, 8)
scala> val nums = odds ++ evens
nums: List[Int] = List(1, 3, 5, 7, 9, 2, 4, 6, 8)
我们可以使用“ :: ”将单个项目附加到列表的前面。
scala> val zeroToNine = 0 :: nums
zeroToNine: List[Int] = List(0, 1, 3, 5, 7, 9, 2, 4, 6, 8)
并使用sorted对列表进行排序 ,并使用reverse对其进行反转 ,然后按顺序进行操作。
scala> zeroToNine.sorted
res42: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> zeroToNine.reverse
res43: List[Int] = List(8, 6, 4, 2, 9, 7, 5, 3, 1, 0)
scala> zeroToNine.sorted.reverse
res44: List[Int] = List(9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
最后一行说的是“获取zeroToNine ,从中获取一个新的排序列表,然后反转该列表。” 请注意,调用这些函数永远不会更改zeroToNine本身! 这是因为List是不可变的 :您无法更改它,因此所有这些操作都将返回新的List。 Lists的此属性带来了很多好处,我们稍后会再讲。
注意:不变性不同于val / var区别。 人们通常认为val变量是不可变的,但事实并非如此-它是固定的,无法重新分配。 以下示例均涉及不可变列表,但固定变量为val,而可重分配变量为var 。
scala> val fixed = List(1,2)
fixed: List[Int] = List(1, 2)
scala> fixed = List(3,4)
<console>:8: error: reassignment to val
fixed = List(3,4)
^
scala> var reassignable = List(5,6)
reassignable: List[Int] = List(5, 6)
scala> reassignable = List(7,8)
reassignable: List[Int] = List(7, 8)
人们经常想对列表做的一件事就是直接访问其元素。 这是通过索引到列表中来完成的,第一个元素从0开始,第二个元素从1开始,依此类推。
scala> odds
res48: List[Int] = List(1, 3, 5, 7, 9)
scala> odds(0)
res49: Int = 1
scala> odds(1)
res50: Int = 3
以0开头的第一个元素的索引是计算机科学的标准实践。 乍一看似乎很奇怪,但是您很快就会习惯它。
我们当然可以使用任何Int表达式来访问列表中的项目。
scala> zeroToNine(3)
res63: Int = 5
scala> zeroToNine(5-2)
res64: Int = 5
scala> val index = 3
index: Int = 3
scala> zeroToNine(index)
res65: Int = 5
如果我们要求索引等于或大于列表中的元素数,则会出现错误。
scala> odds(10)
java.lang.IndexOutOfBoundsException: 10
at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:51)
at scala.collection.immutable.List.apply(List.scala:45)
at .<init>(<console>:9)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $export(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:592)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$10.apply(IMain.scala:828)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:31)
at java.lang.Thread.run(Thread.java:680)
综观所有这些,您可能会想“ WTF?” 这称为堆栈跟踪,它为您提供了一些代码中发生问题的详细位置。 对于刚开始的程序员来说,这可能看起来让人不知所措和令人生畏-您可以暂时放心地使用它,但是不久之后,就必须能够使用堆栈跟踪来识别代码中的问题并加以解决。
另一个有用的方法是slice ,它为您提供了从一个索引到但不包括另一个索引的子列表。
scala> zeroToNine
res55: List[Int] = List(0, 1, 3, 5, 7, 9, 2, 4, 6, 8)
scala> zeroToNine.slice(2,6)
res56: List[Int] = List(3, 5, 7, 9)
因此,该切片为我们提供了一个列表,其中包含从索引2(第三个元素)到索引5(第六个元素)的元素。
简短地返回到Strings -除了length以外,其他List方法也可以使用它们。
scala> val artist = "DJ Shadow"
artist: java.lang.String = DJ Shadow
scala> artist(3)
res0: Char = S
scala> artist.slice(3,6)
res1: String = Sha
scala> artist.reverse
res2: String = wodahS JD
scala> artist.sorted
res3: String = " DJSadhow"
在包含数字的列表上,我们可以使用sum方法。
scala> odds.sum
res59: Int = 25
scala> multinomial.sum
res60: Double = 1.0
但是,如果列表包含非数字值,则sum无效。
scala> groceryList.sum
<console>:9: error: could not find implicit value for parameter num: Numeric[java.lang.String]
groceryList.sum
^
发生的事情是Scala涉及隐式的一些非常酷和有用的自动魔术行为。 我们稍后会再讨论,但现在您可以在整数和双精度列表中愉快地使用sum 。
我们经常想对列表做的一件事是以某种视觉上有用的方式获得其内容的String表示。 例如,我们可能希望杂货店列表是一个字符串,每行一个项目,或者是一个整数列表,每个元素之间用逗号分隔。 mkString方法可以满足我们的需求。
scala> groceryList.mkString("\n")
res22: String =
apples
milk
butter
scala> odds.mkString(",")
res23: String = 1,3,5,7,9
是否想知道列表中是否包含特定元素? 使用包含在列表中。
scala> groceryList.contains("milk")
res4: Boolean = true
scala> groceryList.contains("coffee")
res5: Boolean = false
现在,我们介绍另一个最重要的基本类型布尔值 。 它们在条件执行中起主要作用,我们将在下一个教程中介绍。
实际上,还有许多可用的列表方法,您可以通过转到Scala API中的 List条目来查看 。 API代表应用程序编程接口—换句话说,它是您可以使用Scala编程语言的各个组件执行的一系列规范的集合。 我将尽力为您提供您现在需要的方法,但是最终您将需要能够查看Scala类型的API条目,以查看可用的方法,它们的作用以及如何使用它们。 。
我们未涉及的List上最重要的方法是map , filter , foldLeft和reduce 。 稍后我们将详细介绍给他们,但现在这里有个预告片,应该使您对它们的工作有直观的认识。
scala> val odds = List(1,3,5,7,9)
odds: List[Int] = List(1, 3, 5, 7, 9)
scala> odds.map(1+)
res6: List[Int] = List(2, 4, 6, 8, 10)
scala> odds.filter(4<)
res7: List[Int] = List(5, 7, 9)
scala> odds.foldLeft(10)(_ + _)
res8: Int = 35
scala> odds.filter(6>).map(_.toString).reduce(_ + "," + _)
res9: java.lang.String = 1,3,5
现在我们开始运行。 :)
参考: Scala入门程序员的第一步,Bcompose博客上JCG合作伙伴 Jason Baldridge的 第二部分 。
相关文章 :
- Scala教程– Scala REPL,表达式,变量,基本类型,简单函数,保存和运行程序,注释
- Scala教程–使用if-else块和匹配条件执行
- Scala教程–迭代,用于表达式,产量,图,过滤器,计数
- Scala教程–正则表达式,匹配
- Scala教程–使用scala.util.matching API进行正则表达式,匹配和替换
- Scala教程–地图,集合,groupBy,选项,展平,flatMap
- Scala教程– scala.io.Source,访问文件,flatMap,可变地图
- Scala教程–对象,类,继承,特征,具有多个相关类型的列表,适用
- Scala教程–脚本编写,编译,主要方法,函数的返回值
- Scala教程– SBT,scalabha,软件包,构建系统
- Scala教程–代码块,编码样式,闭包,scala文档项目
- Scala中功能组合的乐趣
- Scala如何改变我对Java代码的思考方式
- Scala中删除了Java的哪些功能?
- 用Scala测试
- 每个程序员都应该知道的事情
翻译自: https://www.javacodegeeks.com/2011/09/scala-tutorial-tuples-lists-methods-on.html
scala 字符串转数组