scala学习六: 数组的使用
2014-08-02 15:22
281 查看
(1)scala中的option的使用:
Scala 提供了一种普通的函数方法,打破了这一僵局。在某些方面,
“无值” 的可能性,而不需要语言类型系统大费周折地支持这个概念。实际上,使用
注意,Scala
map 中找到键。如果它可以表示 map 上存在某个键,但是有对应的 null 值,这一点特别重要了。
通常,当处理
“启用” 类型和/或值,更不用说在定义中将值绑定到变量、在
元组对应与Java中的bean对象(再想想,和c++/c中的结构体也是同一个东西)
什么是元组:一组数据的集合
数组的使用:
(1)对数组进行遍历
函数式编程提倡不可变对象:如下通过map操作创建出一个新的programmer Array数组
— 结果并不是列表的最后一个元素(通过
在列表中进行递归处理:
在使用
— 它引入了一些很有趣的规则。它的语法在函数语言中非常常见,因此 Scala 的创建者选择支持这种语法,但是要正确、普遍地使用这种语法,必须使用一种比较古怪的规则:任何以冒号结束的 “名称古怪的方法” 都是右关联(right-associative)的,这表示整个表达式从它的最右边的
当然了,列表也可以与模式匹配结合:
中的每一个表达式将隐式返回一个值;在本例中,模式匹配表达式的结果是递归调用
Scala 提供了一种普通的函数方法,打破了这一僵局。在某些方面,
Option类型或
Option[T],并不重视描述。它是一个具有两个子类
Some[T]和
None的泛型类,用来表示
“无值” 的可能性,而不需要语言类型系统大费周折地支持这个概念。实际上,使用
Option[T]类型可以使问题更加清晰(下一节将用到)。
def simpleOptionTest = { val footballTeamsAFCEast = Map("New England" -> "Patriots", "New York" -> "Jets", "Buffalo" -> "Bills", "Miami" -> "Dolphins", "Los Angeles" -> null) println(footballTeamsAFCEast.get("Miami"), Some("Dolphins")) println() println(footballTeamsAFCEast.get("Miami").get, "Dolphins") println() println(footballTeamsAFCEast.get("Los Angeles"), Some(null)) println() println(footballTeamsAFCEast.get("Sacramento"), None) println() }结果如下:
(Some(Dolphins),Some(Dolphins)) (Dolphins,Dolphins) (Some(null),Some(null)) (None,None)
注意,Scala
Map中
get的返回值实际上并不对应于传递的键。相反,它是一个
Option[T]实例,可以是与某个值有关的
Some(),也可以是
None,因此可以很清晰地表示没有在
map 中找到键。如果它可以表示 map 上存在某个键,但是有对应的 null 值,这一点特别重要了。
通常,当处理
Option[T]时,程序员将使用模式匹配,这是一个非常函数化的概念,它允许有效地
“启用” 类型和/或值,更不用说在定义中将值绑定到变量、在
Some()和
None之间切换,以及提取
Some的值(而不需要调用麻烦的
get()方法)。
@Test def optionWithPM = { val footballTeamsAFCEast = Map("New England" -> "Patriots", "New York" -> "Jets", "Buffalo" -> "Bills", "Miami" -> "Dolphins") def show(value : Option[String]) = { <span style="background-color: rgb(192, 192, 192);"> value match { case Some(x) => x case None => "No team found" }</span> } assertEquals(show(footballTeamsAFCEast.get("Miami")), "Dolphins") }
元组对应与Java中的bean对象(再想想,和c++/c中的结构体也是同一个东西)
什么是元组:一组数据的集合
import java.util.Date def simpleTuples() = { val tedsStartingDateWithScala = Date.parse("3/7/2006") val tuple = ("Ted", "Scala", tedsStartingDateWithScala) println(tuple._1, "Ted") println(<span style="background-color: rgb(192, 192, 192);">tuple._2</span>, "Scala") println(tuple._3, tedsStartingDateWithScala) }从元组中去数据的操作如上标记处
数组的使用:
(1)对数组进行遍历
object ArrayExample1 { def main(args : Array[String]) : Unit = { for (i <- 0 to args.length-1) { System.out.println(args(i)) } } }
object ArrayTest extendsApplication { import org.junit._, Assert._ @Test def testFilter = { val programmers = Array( new Person("Ted", "Neward", 37, 50000, Array("C++", "Java", "Scala", "Groovy", "C#", "F#", "Ruby")), new Person("Amanda", "Laucher", 27, 45000, Array("C#", "F#", "Java", "Scala")), new Person("Luke", "Hoban", 32, 45000, Array("C#", "Visual Basic", "F#")), new Person("Scott", "Davis", 40, 50000, Array("Java", "Groovy")) ) // Find all the Scala programmers ... val scalaProgs = programmers.filter((p) => p.skills.contains("Scala") ) // Should only be 2 assertEquals(2, scalaProgs.length) // ... now perform an operation on each programmer in the resulting // array of Scala programmers (give them a raise, of course!) // scalaProgs.foreach((p) => p.salary += 5000) // Should each be increased by 5000 ... assertEquals(programmers(0).salary, 50000 + 5000) assertEquals(programmers(1).salary, 45000 + 5000) // ... except for our programmers who don't know Scala assertEquals(programmers(2).salary, 45000) assertEquals(programmers(3).salary, 50000) } testFilter }
函数式编程提倡不可变对象:如下通过map操作创建出一个新的programmer Array数组
@Test def testFilterAndMap = { val programmers = Array( new Person("Ted", "Neward", 37, 50000, Array("C++", "Java", "Scala", "C#", "F#", "Ruby")), new Person("Amanda", "Laucher", 27, 45000, Array("C#", "F#", "Java", "Scala")), new Person("Luke", "Hoban", 32, 45000, Array("C#", "Visual Basic", "F#")) new Person("Scott", "Davis", 40, 50000, Array("Java", "Groovy")) ) // Find all the Scala programmers ... val scalaProgs = programmers.filter((p) => p.skills.contains("Scala") ) // Should only be 2 assertEquals(2, scalaProgs.length) // ... now perform an operation on each programmer in the resulting // array of Scala programmers (give them a raise, of course!) // def raiseTheScalaProgrammer(p : Person) = { new Person(p.firstName, p.lastName, p.age, p.salary + 5000, p.skills) } val raisedScalaProgs = scalaProgs.map(raiseTheScalaProgrammer) assertEquals(2, raisedScalaProgs.length) assertEquals(50000 + 5000, raisedScalaProgs(0).salary) assertEquals(45000 + 5000, raisedScalaProgs(1).salary) }
函数性列表
class ListTest { import org.junit._, Assert._ @Test def simpleList = { val myFirstList = List("Ted", "Amanda", "Luke") assertEquals(myFirstList.isEmpty, false) assertEquals(myFirstList.head, "Ted") assertEquals(myFirstList.tail, List("Amanda", "Luke") assertEquals(myFirstList.last, "Luke") } }注意,构建列表与构建数组十分相似;都类似于构建一个普通对象,不同之处是这里不需要 “new”(这是 “case 类” 的功能,我们将在未来的文章中介绍到)。请进一步注意
tail方法调用的结果
— 结果并不是列表的最后一个元素(通过
last提供),而是除第一个元素以外的其余列表元素。
在列表中进行递归处理:
@Test def recurseList = { val myVIPList = List("Ted", "Amanda", "Luke", "Don", "Martin") def count(VIPs : List[String]): Int = //声明了返回值的 { if (VIPs.isEmpty) 0 else count(VIPs.tail) + 1 } assertEquals(count(myVIPList), myVIPList.length) }不使用list的构造函数而是使用另一种更方便的操作:
@Test def recurseConsedList = { val myVIPList = "Ted" :: "Amanda" :: "Luke" :: "Don" :: "Martin" :: Nil def count(VIPs : List[String]) : Int = { if (VIPs.isEmpty) 0 else count(VIPs.tail) + 1 } assertEquals(count(myVIPList), myVIPList.length) }注意:“::”的规则:
在使用
::方法时要小心
— 它引入了一些很有趣的规则。它的语法在函数语言中非常常见,因此 Scala 的创建者选择支持这种语法,但是要正确、普遍地使用这种语法,必须使用一种比较古怪的规则:任何以冒号结束的 “名称古怪的方法” 都是右关联(right-associative)的,这表示整个表达式从它的最右边的
Nil开始,它正好是一个
List。因此,可以将
::认定为一个全局的
::方法,与
String的一个成员方法(本例中使用)相对;这又表示您可以对所有内容构建列表。在使用
::时,最右边的元素必须是一个列表,否则将得到一个错误消息。
当然了,列表也可以与模式匹配结合:
@Test def recurseWithPM = { val myVIPList = "Ted" :: "Amanda" :: "Luke" :: "Don" :: "Martin" :: Nil //表示一个空list list[nothing] def count(VIPs : List[String]) : Int = { VIPs match { case h :: t => count(t) + 1 case Nil => 0 } } assertEquals(count(myVIPList), myVIPList.length) }在第一个
case表达式中,将提取列表头部并绑定到变量 h,而其余部分(尾部)则绑定到 t;在本例中,没有对 h 执行任何操作(实际上,更好的方法是指明这个头部永远不会被使用,方法是使用一个通配符 _ 代替 h,这表明它是永远不会使用到的变量的占位符)。但是 t 被递归地传递给
count,和前面的示例一样。还要注意,Scala
中的每一个表达式将隐式返回一个值;在本例中,模式匹配表达式的结果是递归调用
count + 1,当达到列表结尾时,结果为
0。
相关文章推荐
- Scala入门学习笔记三--数组使用
- Spark学习使用笔记 - Scala篇(2)- 数组
- 大数据学习之Scala中数组(Array)与循环控制for联合使用学习(4)
- Scala入门学习笔记三--数组使用
- Spark学习使用笔记 - Scala篇(2)- 数组
- scala 学习(六)——使用filter创建数组
- [Shell学习笔记] 数组、关联数组和别名使用
- 学习笔记之cocos2d-x2.1.1实现读取.plist文件(使用数组CCArray)
- php学习笔记(7):PHP数组的创建修改使用
- c#学习体会:使用 ref 和 out 传递数组(downmoon)
- C语言学习10:结构体,结构体应用,联合用法,枚举,fopen函数使用,fseek,ftell的作用和文件结束符EOF,数组和文件交换数据,个人信息管理。
- 韩顺平_PHP程序员玩转算法公开课(第一季)07_使用数组实现堆栈_学习笔记_源代码图解_PPT文档整理
- 学习笔记之cocos2d-x2.1.1实现读取.plist文件(使用数组CCArray)
- c#学习体会:使用 ref 和 out 传递数组(downmoon)
- c#学习体会:使用 ref 和 out 传递数组(downmoon)
- C语言学习6 :指针的定义,指针类型要合法,指针要初始化,指针做函数参数,数组和指针的通用性,指针+1所代表的空间,void * 指针,交换函数中的指针,数组和字符型指针区别,字符型指针的应用,使用指针完成字符操作函数
- 每日学习总结:根据给定的时间段,返回时间段内的月(年/季度)的数组、使用JavascriptSerializer类将DataTable序列化和反序列化
- 学习数组时的一些知识点(来源书上,仅供个人学习使用)
- PHP学习第六节----数组的基础使用
- c#学习体会:使用 ref 和 out 传递数组(downmoon)