?? Object-oriented programming and functional programming are the two most mainstream programming paradigms, and the discussion about the merits and demerits of these two paradigms has never stopped. In fact, programmers who really understand the two programming paradigms do not arbitrarily say that these are the best of both worlds, because no programming language has a panacea to make its users a good programmer. In fact, the classic object-oriented programming language like Java can also see the shadow of functional programming, if you have used the visitor pattern, the command pattern, if you have used the interface callback, you have actually used the concept of functional programming, and in the new version of Java, has started to support lambda expressions and functional interfaces, all of which are improvements made by Java in support of functional programming. Similarly, we can write object-oriented style code in C language. In fact, as long as you can write high-quality code in the right place using the appropriate programming paradigm, we should not let our programs be confined to a programming paradigm, as a good programmer would never claim allegiance to a language (a lot of crappy three-stream programmers would do that).
Simple array filtering
?? Let's look at an example where a set of even numbers is placed in an array, as the traditional practice is.
var evens = [Int]()for i in 1...10 { if i % 2 == 0 { evens.append(i) }}println(evens) // [2, 4, 6, 8, 10]
?? If we use function programming, we can do the same thing with the following code. And we will judge even-numbered code as a function, which significantly increases the reusability of the code.
func isEven(number: Int) -> Bool { return20}var evens = Array(1...10).filter(isEven)println(evens)
?? Of course, it can also be written as follows.
varArray(1...10).filter{ $020 }println(evens) // [2, 4, 6, 8, 10]
?? Clearly, functional programming has some of the following features:
?? -Higher order functions: functions can be passed to functions as arguments to functions.
?? -Class Citizen: You can use a function as a variable.
?? -Closures: You can use anonymous functions.
Attribution (Reducing)
?? If you want to add another feature to the above example, add the even sums in the array, as the traditional practice looks like.
var evens = [Int]()forin1...10 { if20 { evens.append(i) }}var0forin evens { evenSum += i}println(evenSum) // 30
?? Rewrite the above code in a functional programmatic way, as shown below.
var evenSum = Array(1...10) .filter$020} .reduce(0$0$1 }println(evenSum) // 30
?? If you want to understand how reduce works, you can look at the prototype of a function.
func reduce<U>(initial: U, combine: @noescape (U, T) -> U) -> U
Indexer
?? Let's do it again. A new task is indexed for the elements in the array. If there is a series of strings in an array, we want to create a new storage structure by using the first letter of the string as an index, as shown in the traditional practice.
ImportFoundation Letwords = ["Cat","Chicken","Fish","Dog","Mouse","Pig","Monkey"]typealias Entry = (Character, [String]) func Buildindex (words: [String]) [Entry] {varresult = [Entry] ()varLetters = [Character] () forWordinchwords { LetFirstletter = Character (Word.substringtoindex (Advance (Word.startindex,1)). uppercasestring)if!contains (Letters, Firstletter) {letters.append (Firstletter)}} forLetterinchLetters {varWordsforletter = [String] () forWordinchwords { LetFirstletter = Character (Word.substringtoindex (Advance (Word.startindex,1)). uppercasestring)ifFirstletter = = Letter {wordsforletter.append (Word)}} result.append (letter, WOR Dsforletter))}returnResult//[("C", ["Cat","Chicken"]), ("F", ["Fish"]), ("D", ["Dog"]), ("M", ["Mouse","Monkey"]), ("P", ["Pig"])]println (Buildindex (words))
?? With functional programming, you can rewrite your code to look like the following.
ImportFoundation Letwords = ["Cat","Chicken","Fish","Dog","Mouse","Pig","Monkey"]typealias Entry = (Character, [String]) func distinct<T: equatable> (Source: [T]) [T] {varunique = [T] () forIteminchSOURCE {if!contains (unique, item) {Unique.append (item)}}returnUnique}func Buildindex (words: [String]) [Entry] {func Firstletter (str:string) Character {returnCharacter (Str.substringtoindex (Advance (Str.startindex,1)). uppercasestring)}returnDistinct (Words.map (firstletter)). Map { (letter) Entryinch return(Letter, Words.filter {firstletter ($0) = = Letter})}}println (Buildindex (words))
Curry (currying)
?? To understand the curry, let's take a look at the following example.
"5,7;3,4;55,6"// ["5,7""3,4""55,6"]println(data.componentsSeparatedByString(";"))// ["5""7;3""4;55""6"]println(data.componentsSeparatedByString(","))
?? In the example above, we use the componentsseparatedbystring () method of the string to split the string into an array of strings based on the specified character (string). Sometimes we may need to split the occurrences of the string with the specified character (string), so we can do this, as shown below.
ImportFoundation Letdata ="5,7;3,4;55,6"Func Createsplitter (separator:string) (String -[String]) {func Split (source:string) [String] {returnSource.componentsseparatedbystring (Separator)}returnSplit LetCommasplitter = Createsplitter (",")//["5","7;3","4;55","6"]println (Commasplitter (data))//["5,7","3,4","55,6"] LetSemicolonsplitter = Createsplitter (";") println (Semicolonsplitter (data))
?? Obviously, as we have done above, we can use two splitter commasplitter and Semicolonsplitter repeatedly to split the string without having to call the split function of the string and specify the split character (string). This programming concept is often referred to as "partial application" (partial application), which is the principle of fixing one or more parameters in a function first, creating a new function. Let's keep looking down.
ImportFoundation Letdata ="5,7;3,4;55,6"Func Createsplitter (separator:string) (source:string), [String] {returnSource.componentsseparatedbystring (Separator)} LetCommasplitter = Createsplitter (",")//["5","7;3","4;55","6"]println (Commasplitter (Source: Data))//["5,7","3,4","55,6"] LetSemicolonsplitter = Createsplitter (";") println (Semicolonsplitter (Source: Data))
?? Doesn't that look more elegant? Pass in a parameter first, then pass another parameter later to implement the complete function, this is actually the so-called function of the curry. Let's look at one more example.
add(onetwothree: Int) -> Int { returnonetwothreesumadd(123)println(sum)
?? We can also write the rewrite add () function.
add(one: Int)(two: Int)(three: Int) -> Int { returnonetwothreeadd(1)let step2 = step1(two2)let step3 = step2(three3)println(step3)
?? Let's take another example to implement a curry string fill function.
func stringpadding (Startindex:int, paddingstring: string ) (Source: string , Length:int) -> string {return source Stringbypaddingtolength (length, withstring:paddingstring, Startingatindex:startindex)} let text = "Swift" let dottedpadding = stringpadding (0 , "." ) let paddingtext = dottedpadding (Source:text, Length: 10 ) println (paddingtext) //Swift ...
[Introduction to Serial]swift development]---functional programming