*Functional programming is a programming paradigm that emphasizes calculations via mathematical-style functions, immutability and expressiveness, and minimizes the use of variables and state.
Since there's minimal shared state and each function is like an island in the ocean of your app, it makes things easier to test. Functional programming has also come into popularity because it can make concurrency and parallel processing easier to work with. That's one more thing in your toolbox to improve performance in these days of multi-core devices.
*
func isEven(number: Int) -> Bool { return number % 2 == 0 } evens = Array(1...10).filter(isEven) println(evens)
The Array(1...10) section is a simple and convenient way to create an array containing the numbers 1 through 10. The range operator 1...10 creates a Range you pass to the array's initializer.
The filter statement is where the functional programming magic takes place. This method, exposed by Array, creates and returns a new array that contains only the items for which the given function returns true. In this example, isEven is supplied to filter.
evens = Array(1...10).filter { (number) in number % 2 == 0 } println(evens)
The above example demonstrates that the compiler infers the type of the parameter number and return types of the closure from its usage context.
evens = Array(1...10).filter { $0 % 2 == 0 } println(evens)
The above uses argument shorthand notation, implicit returns, type inference.
*
func myFilter<T>(source: [T], predicate:(T) -> Bool) -> [T] { var result = [T]() for i in source { if predicate(i) { result.append(i) } } return result }
evens = myFilter(Array(1...10)) { $0 % 2 == 0 } println(evens)
The main difference is that you supply the condition being checked as a function rather than hard-code it.
*The first parameter is the initial value, which is of type U. In your current code, the initial value is 0 and is of type Int (hence U is Int in this case). The second argument is the combine function that is excited once for each element of the array.
Combine takes two arguments: the first, of type U, is the result of the previous invocation of combine; the second is the value of the array element that is being combined. The result returned by reduce is the value returned by the last combine invocation.
*
let numbers = Array(1...10) .reduce("numbers: ") {(total, number) in total + "\(number) "} println(numbers)
This produces the following output:
numbers: 1 2 3 4 5 6 7 8 9 10
*
extension Array { func myReduce<T, U>(seed:U, combiner:(U, T) -> U) -> U { var current = seed for item in self { current = combiner(current, item as T) } return current } }
*map creates a new array with the results of calls to the supplied closure for each element in the supplied array. You use map to perform transformations; in this case, map transforms an array of type [String] into an array of type [Character].