Scala Functional Programming (C) and functions set Scala

Recap:

scala functional programming (ii) basic grammar describes scala

scala functional programming (ii) basic grammar describes scala

As already described a little common syntax and object-oriented knowledge scala some brief, this time to add the last chapter, will introduce the main functions and collections.

Note Oh, functions and methods are not the same, which is defined in the class, there may be a separate function (strictly speaking, inside Scala, each function is a class)

A set of presentation .scala

Remember apply the method in the previous chapter object of it, a lot of data structure actually used it, so that we can directly use List (...) so to create a List, without having to manually new one.

PS: Note, scala default data structures are immutable, that is a List, not delete, or add new elements. Of course, there are "variable" data structure, it will be introduced to the back.

1.1 List

Thanks to apply the method, we can not to create a new data structure by new.

//通过工厂,新建一个List,这个List是不可变的
scala> val numbers = List(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)
numbers: List[Int] = List(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)

1.2 yuan group Tuple

Tuple this concept more widely application in python, it can be a variety of data types (Int, String, Double, etc.) packaged together

scala> val tup = (1,1,2.1,"tuple",'c')  //将多种不同数据结构打包一起,可以有重复
tup: (Int, Int, Double, String, Char) = (1,1,2.1,tuple,c)

But in the scala, Tuple length is limited, and that is a Tuple can only have up to 22 elements.

scala> val tup = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)
tup: (Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int) = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21)

//一个Tuple超过22个元素,报错了
scala> val tup = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)
<console>:1: error: too many elements for tuple: 23, allowed: 22
val tup = (0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22)

You can see above, once a Tuple more than 22 elements will be incorrect report. As for why this magic number is 22, it seems to have been not a single argument. Some people joked that 23 fishes, because the name has a movie called "The Number 23" ~~

1.3 Map and Option

Before saying Map, we need to introduce Option, because the Map is kept inside Option, the later introduction.

Option translation is an option, in essence, it really is an option that tells you it exists or not. Or illustrate it with an example:

//Option里面可以存普通数据类型
scala> val optionInt = Option(1)
optionInt: Option[Int] = Some(1)

scala> optionInt.get
res8: Int = 1
//但一个Option也可能为空
scala> val optionNone = Option(null)
optionNone: Option[Null] = None
//当Option里面是空的时候,是get不出东西的,还会报错
scala> optionNone.get
java.util.NoSuchElementException: None.get
  at scala.None$.get(Option.scala:347)
  at scala.None$.get(Option.scala:345)
  ... 32 elided
//这个时候可以判断它就是空的
scala> optionNone.isEmpty
res11: Boolean = true
//但可以用getOrElse()方法,当Option里面有东西的时候,就返回那个东西,如果没有东西,就返回getOrElse()的参数的内容
scala> optionNone.getOrElse("this is null")  //里面没东西
res12: String = this is null
scala> optionInt.getOrElse("this is null") //里面有东西
res15: Any = 1

Besides Map, Map type value of which is not the type of data you assigned, but Option. That Map (key -> Option, key1 -> Option).

scala> val map = Map("test1" -> 1,"test2" -> 2)
map: scala.collection.immutable.Map[String,Int] = Map(test1 -> 1, test2 -> 2)

scala> map.get("test1")
res16: Option[Int] = Some(1)

scala> map.get("test3")
res17: Option[Int] = None

scala> map.get("test3").getOrElse("this is null")
res18: Any = this is null

What this benefit is it? Remember the java inside, each had to make painful judgment of the case do java is empty. In scala, all these troubles do not exist. With Option, my mother no longer have to worry about NullPointerException friends.

1.4 commonly used functions combinator

Anonymous function

A collection of sub-function combination, it certainly had to first anonymous function. If there is a lambda expression used in python, it should be very aware of this way of.

As mentioned earlier, the scala, the function is an object, an anonymous function is also a function. Here is a simple example:

//创建一个匿名函数
scala> val addOne = (x: Int) => x + 1
addOne: (Int) => Int = <function1>

scala> addOne(1)
res4: Int = 2

Note that the function which can not return, the final surface that x + 1 is the anonymous function's return value.

map,reduce

Because of the emergence of hadoop, MapReduce are saying rotten. Although the Hadoop Mapreduce originated from the functional map and reduce, but in fact the two are not the same. Interested can look at before I wrote one: from divide and conquer algorithm to Hadoop MapReduce

Functional map inside it, Roughly speaking, there are actually quite a loop for the return value.

scala> val list = List(1,2,3)
list: List[Int] = List(1, 2, 3)

scala> list.map(_ + 1)   //这里的(_+1)其实就是一个匿名函数 //让List中每一个元素+1,并返回
res29: List[Int] = List(2, 3, 4)

As to reduce it, it is like a for loop, each cycle is just not map the current element, in addition to reduce the current element, as well as the results of the last cycle, or take a look at an example:

scala> list.reduce((i,j) => i + j)  //两个两个一起循环,这里是让两个相加
res28: Int = 6

Such as the example above, there are three numbers 1,2,3. The first cycle of the two is 1,2,1 + 2 equals 3, the second cycle is the last of the original results of 3 and 3, 3 + 3 equals 6, the result is 6.

filter

filter name suggests Italian, is the filter means, can pass into the filter in an anonymous function that returns a Boolean value. Returns true is retained returns to discard false.

scala> val numbers = List(1, 2, 3, 4)
numbers: List[Int] = List(1, 2, 3, 4)

//过滤出余2等于0的
scala> numbers.filter((i: Int) => i % 2 == 0)
res0: List[Int] = List(2, 4)

foldLeft

This and reduce similar, but also to traverse, in addition to the current element, as well as the results of the previous iteration. FoldLeft difference is that there is an initial value.

scala> val numbers = List(1, 2, 3, 4)
numbers: List[Int] = List(1, 2, 3, 4)

//(m: Int, n: Int) => m + n这部分是一个匿名函数
scala> numbers.foldLeft(0)((m: Int, n: Int) => m + n)
res30: Int = 10

Two .scala function

In front there is introduced to the function is the object. Why function can be directly run it? In fact, thanks to this object's apply this syntax sugar.

Partial function

Partial function (PartialFunction), in a sense, partial function is very important in a scala syntax sugar.

It is a long way partial function:

PartialFunction [A, B] // receives a parameter of type A, type B return parameters

It is worth mentioning that, scala has a keyword case, it is to use partial function. Continuing the example sub:

//下面的case就是一个偏函数PartialFunction[Int, String]
scala> val one: PartialFunction[Int, String] = { case 1 => "one" }
one: PartialFunction[Int,String] = <function1>

scala> one(1)
res11: String = Int

scala> one("one")
<console>:13: error: type mismatch;
 found   : String("one")
 required: Int
       one("one")

case keyword match types or values ​​in line with the conditions, if not met, will get an error. Internal implementation is not introduced, we know that this is common syntactic sugar like.

And this case is also the realization scala keyword pattern matching, an essential part, are interested in children's shoes can look me this: scala pattern matching detailed analysis

A common application of it to say here, there is a sub-function combination collect, the parameters it needs is a partial function. Let's look at an interesting example:

//这个list里面的Any类型
scala> val list:List[Any] = List(1, 3, 5, "seven")
list: List[Any] = List(1, 3, 5, seven)

//使用map会报错,因为map接收的参数是普通函
scala> list.map { case i: Int => i + 1 }
scala.MatchError: seven (of class java.lang.String)
  at $anonfun$1.apply(<console>:13)
  at $anonfun$1.apply(<console>:13)
  at scala.collection.immutable.List.map(List.scala:277)
  ... 32 elided

  //但如果用collect函数就可以,因为collect接收的参数是偏函数,它会自动使用偏函数的一些特性,所以可以自动过滤掉不符合的数据类型
scala> list.collect { case i: Int => i + 1 }
res15: List[Int] = List(2, 4, 6)

Since partial collect received parameter is a function, it will automatically use the characteristics of partial functions, automatic filtering of the data type does not match, the map could not do.

Part of the application function

The so-called part of the application means, that is, when a function is called, only a portion of the parameters can be passed. And this will generate a new function, for instance look at it:

//定义一个打印两个输出参数的函数
scala> def partial(i:Int,j:Int) : Unit = {
     |     println(i)
     |     println(j)
     | }
partial: (i: Int,j: Int)Unit

//赋一个值给上面那个函数,另一个参数不赋值,生成一个新的函数
scala> val partialFun = partial(5,_:Int)
partialFun: Int => Unit = <function1>

//只要一个参数就可以调用啦
scala> partialFun(10)
5
10

Partial application function, the main role is code reuse is also possible to increase a certain code readability.

Of course there are many more interesting usage, followed by the opportunity comes to say.

Function currying

At first, when currying hear very strange. Currie? Hell?

Only later did know that curry Curry is a transliteration from, this is a personal name, was the invention of currying inventor.

Currying function is to accept multiple parameters is converted into a function that accepts a single parameter (first parameter of the first function) and the function returns a new technology that takes the remaining arguments and returns the result.

Specifically look at how to use it:

//我们知道函数可以这样定义,让它接收两个参数
scala> def curring(i:Int)(j: Int): Boolean = {false}
curring: (i: Int)(j: Int)Boolean

//可以把这个函数赋值给一个变量,注意变量的类型
scala> val curringVal:(Int => (Int => Boolean)) = curring _
curringVal: Int => (Int => Boolean) = <function1>

//可以让这个变量接收一个参数,又变成另一个函数了
scala> val curringVal_1 = curringVal(5)
curringVal_1: Int => Boolean = <function1>

//再用这个变量接收一个参数,终于能返回结果了
scala> curringVal_1(10)
res32: Boolean = false

Currying is actually a function of the process of becoming a call chain, and part of the above application function looks like.

This is the first time to see several parts may not know exactly what it is, in fact, one of the main uses of these features are functional dependency injection. The function can be dependent on the function passed to the upper part by this technique as a parameter. Limited space is omitted here first, and then later described.

Conclusion:

The introduction is something scala collections, as well as some of the characteristics function, repeat function is actually an object.

I've always had a point of view, learning new things when some partial rules fixed things, such as grammar. Not all memorize, just know about principle, there is a map on the line.

For example, functional programming scala, or the java OOP, do not need to have finished first grammar school, then learning-related programming philosophy, which in my opinion is a bit cart before the horse.

My general approach is to get to know about the syntax, and then to learn the essence of language. When it comes to not know when, and then turn specific query syntax, after a target, but the syntax becomes less boring.

These are just some of my personal views, then Benpian this is over.

More ~~

Guess you like

Origin www.cnblogs.com/listenfwind/p/11593498.html