OctoberHammer
11/10/2017 - 1:04 PM

FP Swift

//: Playground - noun: a place where people can play

import UIKit
import Foundation
import PlaygroundSupport


let numbers5 = Array(1...10000)
let lazyFiltered = numbers5.lazy.filter {$0 % 2 == 0}
let lazyMap = numbers5.lazy.map {$0 * 2}

//print(lazyFiltered.count)
//print(lazyFiltered.count)
print(lazyMap[5000])



//Custom operator and combining functions
precedencegroup CompositionPrecedence {
    associativity: left
}

infix operator >>>: CompositionPrecedence

func >>> <T,U,V> (lhs: @escaping (T) -> U, rhs: @escaping (U) -> V) -> (T) -> V {
    return {rhs(lhs($0))}
}

func generateRandomNumber(max: Int) -> Int {
    let number = Int(arc4random_uniform(UInt32(max)))
    print("Using number \(number)")
    return number
}

func calculateFactors(number: Int) -> [Int] {
    return (1...number).filter {number % $0 == 0}
}

func reduceToString(numbers: [Int]) -> String {
    return numbers.reduce("Factors: ") {$0 + String($1) + " "}
}


let result1 = reduceToString(numbers: calculateFactors(number: generateRandomNumber(max: 100)))
print(result1)
let combined = generateRandomNumber >>> calculateFactors >>> reduceToString
print(combined(100))


//Chaining functions
let london = (name: "London", continent: "Europe", population: 8_539_000)
let paris = (name: "Paris", continent: "Europe", population: 2_224_000)
let lisbon = (name: "Lisbon", continent: "Europe", population: 530_000)
let rome = (name: "Rome", continent: "Europe", population: 2_627_000)
let tokyo = (name: "Tokyo", continent: "Asia", population: 13_350_000)
let cities = [london, paris, lisbon, rome, tokyo]
let totalPopulation = cities.filter {$0.continent == "Europe"}.reduce(0) { $0 + $1.population}
print(totalPopulation)
let table = cities.filter{$0.population > 2_000_000}.sorted{ $0.population > $1.population}.prefix(upTo: 4).map{"\($0.name) is a big city, with population: \($0.population)"}.joined(separator: "\n")
print(table)



//flatMap reduces one level of Complexity

let myArray = [[[2,3,4], [90,2,30]], [[51,53,59], [1001,1002,1003]]]
let result = myArray.flatMap{$0}
print(result)

let names = ["Taylor", "Paul", "Adele"]
let count = names.reduce(0){ $0 + $1.characters.count}
print(count)

let scoresString = ["100", "95", "85", "90", "100"]
let sortedInt = scoresString.flatMap {Int($0)}.sorted()
print(sortedInt)