Swift函数式编程

2018-08-09  本文已影响18人  NapoleonY

楔子

问题:给定一个数组,找出里面所有的偶数

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let events = numbers.filter { (num : Int) -> Bool in
    return num % 2 == 0
}

面向对象与函数式编程

面向对象
现在要对一个数组进行处理,我可以封装一个工具类,类中可以提供如下方法:

函数式编程
Array为例,如果系统没有提供filter函数,我们可以自己扩展一个类似的函数

extension Array {
    func personlFilter(oprationFunc : (Int) -> Bool) -> [Int] {
        var tempArray = [Int]()
        
        for item in self {
            if oprationFunc(item as! Int) {
                tempArray.append(item as! Int)
            }
        }
        return tempArray
    }
}
// 使用
let newEvents = numbers.personlFilter { (num) -> Bool in
            return num % 3 == 0
        }

如果想让代码更通用,我们还可以使用范型,例如获取字符串数组中包含a的字符串

reduce

reduce是函数式编程中一个常用的函数,它的作用是将集合中的元素按照某种方式合并,合并的规则由调用者决定,代码如下

let totoal = numbers.reduce(5) { (num1 : Int, num2 : Int) -> Int in
            return num1 + num2
        }

上述代码是将numbers数组中的元素求和。reduce接收两个参数

map

map可以对数组中的每一个元素做一次处理。代码如下

let animals = ["Dragon", "Cat", "Tiger", "fdakjfdakf", ""]
        
let animalCount = animals.map { (str : String) -> Int in
    let length = str.count
    return length
}
// [Optional(6), Optional(3), Optional(5), Optional(10), nil]
map巧用示例

根据已知数组,创建一个count相同的对应的数组

let titles = ["头条", "视频", "娱乐", "要问", "体育" , "科技" , "汽车" , "时尚" , "图片" , "游戏" , "房产"]

// 创建每一页对应的controller
let childViewControllers: [ContentViewController] = titles.map { _ -> ContentViewController in
    let controller = ContentViewController()
    controller.view.backgroundColor = UIColor.randomColor
    return controller
}

compactMap

Swift 4.1后,compactMap代替了flatMap,它们与map类似,但compactMap会自动剔除返回数组中的nil,并把Optional解包

let animalFlapCount = animals.compactMap { (str: String) -> Int? in
            let length = str.count
            guard length > 0 else {
                return nil
            }
            return length
        }
//[6, 3, 5, 10]

可以看出,与map返回的结果相比,少了nil

示例

实现一个函数:求0~100(包括0和100)中为偶数并且恰好是其它数字平方的数字

  1. 通常的解法
func evenSquare(from a: Int, to b: Int) ->[Int] {
        var result = [Int]()
        
        for num in a...b where ((num % 2) == 0) {
            if (a...b).contains(num * num) {
                result.append(num * num)
            }
        }
        
        return result
    }
  1. 使用函数式编程的解法
func evenSquare(from :Int, to : Int) -> [Int] {
        /*let res = [Int]()
        let res = (from...to).map { (num) -> Int in
            return num*num
            }.filter { (num) -> Bool in
                return num % 2 == 0
        }*/
        let res = (from...to).map{ $0 * $0}.filter{ $0 % 2 == 0}

        return res
    }

参考

  1. Swift中的函数式编程
  2. iOS面试之道
上一篇 下一篇

猜你喜欢

热点阅读