Scala 函数式程序设计原理(6)--Collections

6.1 Other Collections

Operations on Vectors:

Vectors are created analogously to lists:

val nums = Vector(1, 2, 3, -88)

val peoplr = Vector("Bob", "James", "Peter")

They support the same operations as lists, with the exception of ::

Instrad of x :: xs, there is

  x +: xs  Create a new vector with leading element x, followed by all elements of xs

  xs :+ x  Create a new vector with trailing element x, preceded by all elements of xs

object test {
	val xs = Array(1, 2, 3, 44)               //> xs  : Array[Int] = Array(1, 2, 3, 44)
	xs map (x => x*2)                         //> res0: Array[Int] = Array(2, 4, 6, 88)

	val s = "Hello World"                     //> s  : String = Hello World
	s filter (c => c.isUpper)                 //> res1: String = HW
	s exists (c => c.isUpper)                 //> res2: Boolean = true
	s forall (c => c.isUpper)                 //> res3: Boolean = false

	val pairs = List(1, 2, 3) zip s           //> pairs  : List[(Int, Char)] = List((1,H), (2,e), (3,l))
	pairs.unzip                               //> res4: (List[Int], List[Char]) = (List(1, 2, 3),List(H, e, l))

	s flatMap (c => List(‘.‘, c))             //> res5: String = .H.e.l.l.o. .W.o.r.l.d

	xs.sum                                    //> res6: Int = 50
	xs.max                                    //> res7: Int = 44
	xs.min                                    //> res8: Int = 1
}

6.2 Combinatorial Search and For-Expressions

For-Expression Example:

Let persons be a list of elements of class Person,  with fields name and age.

  case class Person(name: String, age: Int)

To obtain the names of persons over 20 years old, you can write:

for (p <- persons if p.age > 20) yield p.name

which is equivalent to:

persons filter (p => p.age > 20) map (p => p.name)

Syntax of For

A for-expression is of the form

for ( s ) yield e

where s is a sequence of generators and filters, and e is an expression whose value is returned by an iteration.

  • A generator is of the form p <- e, where p is a pattern and e an expression whose value is a collection.
  • A filter is of the form if f where f is a boolean expression.
  • The sequence must start with a generator.
  • If there are several generators in the sequence, the last generators vary faster than the first.

Instead of ( s ), braces { s } can also be used, and then the sequence of generators and filters can be written on multiple lines without require semicolons.

6.3 Combinatorial Search Example

Sets vs Sequences

The principal differences between sets and sequences are:

  1. Sets are unordered; the elements of a set do not have a predefined order in which they appear in the set
  2. sets do not have duplicate elements
  3. The fundamental operation on sets is contains

6.4 Maps

++:

object polynominals {
	class Poly(terms0: Map[Int, Double]) {
		def this(bindings: (Int, Double)*) = this(bindings.toMap)
		val terms = terms0 withDefaultValue 0.0
		def + (other: Poly) = new Poly(terms ++ (other.terms map adjust))

		def adjust(term: (Int,Double)) : (Int, Double) = {
			val (exp, coeff) = term
			exp -> (coeff + terms(exp))
		}

		override def toString =
			(for ((exp , coeff) <- terms.toList.sorted.reverse) yield coeff + "x^" + exp) mkString " + "
	}

	val p1 = new Poly(1 -> 2.0, 3 -> 4.0, 5 -> 6.2)
                                                  //> p1  : week6.polynominals.Poly = 6.2x^5 + 4.0x^3 + 2.0x^1
	val p2 = new Poly(0 -> 3.0, 3 -> 7.0)     //> p2  : week6.polynominals.Poly = 7.0x^3 + 3.0x^0
	p1 + p2                                   //> res0: week6.polynominals.Poly = 6.2x^5 + 11.0x^3 + 2.0x^1 + 3.0x^0
	p1.terms(7)                               //> res1: Double = 0.0
}

foldLeft(more efficiency):

object polynominals {
	class Poly(terms0: Map[Int, Double]) {
		def this(bindings: (Int, Double)*) = this(bindings.toMap)
		val terms = terms0 withDefaultValue 0.0
		def + (other: Poly) = new Poly((other.terms foldLeft terms)(addTerm))
		         def addTerm(terms: Map[Int, Double], term: (Int, Double)): Map[Int, Double] = {           val (exp, coeff) = term           terms + (exp -> (coeff+terms(exp)))         }

		override def toString =
			(for ((exp , coeff) <- terms.toList.sorted.reverse) yield coeff + "x^" + exp) mkString " + "
	}

	val p1 = new Poly(1 -> 2.0, 3 -> 4.0, 5 -> 6.2)
                                                  //> p1  : week6.polynominals.Poly = 6.2x^5 + 4.0x^3 + 2.0x^1
	val p2 = new Poly(0 -> 3.0, 3 -> 7.0)     //> p2  : week6.polynominals.Poly = 7.0x^3 + 3.0x^0
	p1 + p2                                   //> res0: week6.polynominals.Poly = 6.2x^5 + 11.0x^3 + 2.0x^1 + 3.0x^0
	p1.terms(7)                               //> res1: Double = 0.0
}
时间: 2024-10-09 22:01:52

Scala 函数式程序设计原理(6)--Collections的相关文章

Scala 函数式程序设计原理(1)

课程地址:https://www.coursera.org/learn/progfun1/home/welcome 1.1 Programming Paradigms In a restricted sense, a functional programming language is one which does not have mutable variables, or imperative control structures. In a wider sense, a functiona

Scala 函数式程序设计原理(4)--Types and Pattern Matching

4.1 Objects Everywhere Pure Object Orientation: A pure object-oriented language is one in which every value is an object. If the language is based on classes, this means that the type of each value is a class. 4.2 Functions as Objects (x: Int) => x *

Scala函数式编程设计原理 第一课 编程范式(Programming Paradigms)

我使用Scala有一两年的时间了,这门语言仿佛有一种魔力,让人用过就不想放手.Scala给我的整个程序生涯带来了非常深刻的影响,让我学会了函数式编程,让我知道了世界上居然还有这么一种优雅.高效.强大的语言. Scala在国外已经非常流行,但是不知为何,在国内总是不温不火,在此,我特别想为Scala这门语言在国内的发展做一些事情.不才不敢谈Scala的编程经验,因为要成为Scala大神还有很长的路要走,只好翻译一份Scala视频教程以飨读者,大家发现有误的地方,请多多批评指教. 这个视频的作者是S

Scala函数式编程进阶

1 package com.dtspark.scala.basics 2 3 /** 4 * 函数式编程进阶: 5 * 1,函数和变量一样作为Scala语言的一等公民,函数可以直接赋值给变量: 6 * 2, 函数更长用的方式是匿名函数,定义的时候只需要说明输入参数的类型和函数体即可,不需要名称,但是如果你要使用的话,一般会把这个匿名函数赋值给一个变量(其实是val常量),Spark源码中大量存在这种语法,必须掌握: 7 * 3, 函数可以作为参数直接传递给函数,这极大的简化的编程的语法,为什么这

第3课 Scala函数式编程彻底精通及Spark源码阅读笔记

本课内容: 1:scala中函数式编程彻底详解 2:Spark源码中的scala函数式编程 3:案例和作业 函数式编程开始: def fun1(name: String){ println(name) } //将函数名赋值给一个变量,那么这个变量就是一个函数了. val fun1_v = fun1_ 访问 fun1_v("Scala") 结果:Scala 匿名函数:参数名称用 => 指向函数体 val fun2=(content: String) => println(co

虚拟网卡TUN/TAP 驱动程序设计原理

昨天韦哥写了<Linux下Tun/Tap设备通信原理>一文,只提到了两个使用Tun的用户进程之间的通信路径,并没有说明Tun虚拟网卡驱动是如何实现的,而正好看到了这里的一篇讲解这方面的文章,果断转载了,感谢作者,原文在这里:虚拟网卡TUN/TAP 驱动程序设计原理 简介 虚拟网卡Tun/tap驱动是一个开源项目,支持很多的类UNIX平台,OpenVPN和Vtun都是基于它实现隧道包封装.本文将介绍tun/tap驱动的使用并分析虚拟网卡tun/tap驱动程序在linux环境下的设计思路. tun

scala akka 修炼之路6(scala函数式柯里化风格应用场景分析)

胜败兵家事不期,包羞忍耻是男儿--斗牛士fighting,fighting,fighting... 小象学习和使用scala也一段时间了,最初小象学习scala主要为了学习spark生态,但是深入学习scala的一些特性后,深深被scala函数式和面向对象的风格所折服,不得不赞美设计这门语言的设计者.小象大学阶段在使用MATLAB做数据分析和自动化设计时,就非常喜欢使用MATLAB的命令行和面向矩阵运算的风格编写分析代码:喜欢使用java编写层次化和清晰的模块接口,而这些Scala语言设计中都有

【Scala】Scala函数式编程初探

函数式编程 函数式编程是种编程典范,它将电脑运算视为函数的计算.函数编程语言最重要的基础是 λ 演算(lambda calculus).而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值).和指令式编程相比,函数式编程强调函数的计算比指令的执行重要.和过程化编程相比,函数式编程里,函数的计算可随时调用. 命令式编程是面向计算机硬件的抽象,有变量(对应着存储单元),赋值语句(获取,存储指令),表达式(内存引用和算术运算)和控制语句(跳转指令),一句话,命令式程序就是一个冯诺依曼机的指令序列

编码原则实例------c++程序设计原理与实践(进阶篇)

编码原则: 一般原则 预处理原则 命名和布局原则 类原则 函数和表达式原则 硬实时原则 关键系统原则 (硬实时原则.关键系统原则仅用于硬实时和关键系统程序设计) (严格原则都用一个大写字母R及其编号标识,而推荐原则都用小写字母r及其编号标识,对于前者程序员必须严格遵守,而后者则偶尔可以不遵守) 1.一般原则 R100:任何函数和类的代码规模都不应超过200行(不包括注释). 原因:长的函数和类会更复杂,因而难以理解和测试. r101:任何函数和类都应该能完全显示在一屏上,并完成单一的逻辑功能.