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

Posted paulingzhou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Scala 函数式程序设计原理--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 }

 

以上是关于Scala 函数式程序设计原理--Collections的主要内容,如果未能解决你的问题,请参考以下文章

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

Scala最新书籍-《函数式编程科学之Scala实战》pdf级随书代码分享

Scala函数式编程彻底精通

90%的人只是在用scala语法写程序,并不是函数式编程

Scala专题系列 : Scala函数式编程

15Scala隐式转换和隐式参数