Swift高阶函数map,filter,reduce实践

Swift是一门面向协议的语言,在使用Swift时我们已经充分享受到了面向协议编程带给我们的便利,但是Swift相比Obj-C还有一个更重要的优点,那就是对函数式编程提供了很好的支持,其中Swift提供了map,filter,reduce这三个高阶函数(Higher Order function)作为对容器的支持。接下来我会介绍一下这三个函数的使用方法,算是对函数式编程的抛砖引玉,随后会使用这三个函数来优化一个计算文件夹大小的Demo。

map:转换,可以对数组中的元素格式进行转换

//将Int数组转换为String数组
//$0代表数组的元素
let array = [1, 2, 3, 4, 5 , 6, 7]
let result = array.map{
  String($0)
}

filter:过滤,可以对数组中的元素按照某种规则进行过滤

//在array中过滤出偶数
let result2 = array.filter{ 
  $0 % 2 == 0
}

reduce:计算 ,可以对数组中的元素进行计算

//计算数组array元素的和
//在这里$0$1的意义不同,$0代表元素计算后的结果,$1代表元素
//10代表初始化值,在这里可以理解为 $0初始值 = 10
let result3 = array.reduce(10){  
  $0 + $1
}

这三个函数介绍完了,可以看到这三个方法使用起来非常的便利,接下来我会写一个计算文件夹大小的Demo
之前我已经在沙盒中创建了log文件夹,里边存放了四个文件,我们要做的是计算出log文件夹下.pdf格式的文件大小。


folder.png

先写两个方法分别获取文件夹的路径和计算一个文件的大小

//获取文件夹路径
func getFolderPath(folderName: String) -> String{
        let path: NSString = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
        return  path.stringByAppendingPathComponent(folderName)
}
//计算一个文件的大小
func caculateFileSize(path: String) -> UInt64{
        let fileManager = NSFileManager.defaultManager()
        let dic: NSDictionary = try! fileManager.attributesOfItemAtPath(path)
        let size = dic.fileSize()
        return size

    }

使用map,filter,reduce计算文件夹下.pdf格式文件大小

  let folderPath = getFolderPath("log")
  let childFiles = NSFileManager.defaultManager().subpathsAtPath(folderPath)

  //使用filter过滤出.pdf格式的文件
  //在map方法体中,将文件数组转换为size的数组
  //使用reduce计算size数组的和
  //最终返回reduce的计算结果
  let result = childFiles?.filter{
        ($0.componentsSeparatedByString(".")).last == "pdf"

  }.map({ (fileName) -> UInt64 in
        let filePath = folderPath + "/" + fileName
        return caculateFileSize(filePath)

  }) .reduce(0){
        $0 + $1

  }
  print(".pdf文件大小总和为----\(result)")

计算结果:


result.png

在代码中使用filter方法后直接调用了map方法,这是因为高阶函数支持链式调用,高阶函数的特性就是可以以一个函数或多个函数当参数,返回值也可以是一个函数,如果你使用过AutoLayout库 Masonry的话会很习惯这种写法。

以上仅代表我的个人观点,有不足的地方希望大家随时与我沟通

参考:
Swift 烧脑体操(三) - 高阶函数
Swift函数式编程实践



文/Lilin_Coder(简书作者)
原文链接:http://www.jianshu.com/p/32c009fcb13d
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Swift 中,`map` 是一个高阶函数(Higher-Order Function),用于对一个序列中的每个元素进行转换操作并返回一个新的序列。 `map` 函数的基本语法如下: ```swift func map<T>(_ transform: (Element) throws -> T) rethrows -> [T] ``` 其中: - `transform` 是一个接受序列中元素作为输入的闭包,返回一个经过转换的值。闭包必须接受一个参数,其类型必须与序列元素的类型相同,并且返回一个可以转换为 `T` 类型的值。 - `rethrows` 表示该函数可能会抛出异常,但是如果 `transform` 函数没有抛出异常,则 `map` 函数也不会抛出异常。 `map` 函数将序列中的每个元素传递给 `transform` 函数,并将其返回值存储在一个新的数组中,最后返回这个新的数组。 下面是一个简单的例子,演示如何使用 `map` 函数将数组中的每个元素转换为它的平方: ```swift let numbers = [1, 2, 3, 4, 5] let squares = numbers.map { $0 * $0 } print(squares) // 输出 [1, 4, 9, 16, 25] ``` 在这个例子中,我们使用 `map` 函数将 `numbers` 数组中的每个元素传递给闭包 `$0 * $0`,该闭包返回该元素的平方,并将结果存储在 `squares` 数组中。 除了使用简单的闭包进行转换,您还可以使用命名函数作为转换函数。例如: ```swift func double(_ value: Int) -> Int { return value * 2 } let numbers = [1, 2, 3, 4, 5] let doubledNumbers = numbers.map(double) print(doubledNumbers) // 输出 [2, 4, 6, 8, 10] ``` 在这个例子中,我们定义了一个名为 `double` 的函数,该函数接受一个整数作为输入,并返回该整数的两倍。然后我们使用 `map` 函数将 `numbers` 数组中的每个元素传递给该函数,并将结果存储在 `doubledNumbers` 数组中。 总之,`map` 函数是 Swift 中非常有用的一个函数,可以轻松地对序列中的元素进行转换,从而创建一个新的序列。 ### 回答2: 在Swift中,map函数是数组的一个高阶函数,用于对数组中的每个元素进行操作,并返回一个新的数组,新数组的元素是原数组经过操作后得到的结果。 map函数的详细用法如下: ```swift func map<T>(_ transform: (Element) throws -> T) rethrows -> [T] ``` - `_ transform`: 一个闭包表达式,表示对数组元素进行操作的转换方法。 - `rethrows`: 表示闭包可能会抛出错误,该函数也会传递这些错误。 下面是一个简单的示例,使用map函数将一个整数数组中的每个元素加1,并返回新的数组: ```swift let numbers = [1, 2, 3, 4, 5] let result = numbers.map { $0 + 1 } print(result) // 输出 [2, 3, 4, 5, 6] ``` 上述示例中,map函数接收一个闭包表达式,将每个元素加1,并将结果返回。闭包表达式中的`$0`表示数组中的元素。 同样地,我们可以使用map函数对其他类型的数组元素进行操作,如将字符串数组中的每个字符串转换为大写: ```swift let names = ["Alice", "Bob", "Charlie"] let result = names.map { $0.uppercased() } print(result) // 输出 ["ALICE", "BOB", "CHARLIE"] ``` map函数非常灵活,可以根据需求对数组元素进行任意操作,并返回一个新的数组。比如对数组中的对象进行属性提取,或者根据条件过滤元素等等。出于性能优化的考虑,map函数在Swift中是一个惰性求值的方法,只有在需要结果时才会进行操作。 ### 回答3: 在Swift中,map函数是一种高阶函数,可以应用于数组、字典和其他集合类型。它接受一个闭包作为参数,并将该闭包应用于集合中的每个元素,最终返回一个新的集合,其中包含闭包应用于原集合中的每个元素后的结果。 map函数的闭包参数接受原集合类型的元素作为输入,并返回一个可以转换为所需类型的结果。闭包内部的逻辑可以是任意复杂的转换过程,比如对原集合元素进行数学运算、字符串处理等。 下面是一个例子,演示如何使用map函数对数组中的每个元素进行平方操作: ```swift let numbers = [1, 2, 3, 4, 5] let squaredNumbers = numbers.map { $0 * $0 } // squaredNumbers = [1, 4, 9, 16, 25] ``` 在这个例子中,map函数接受一个闭包作为参数,该闭包对数组中的每个元素进行平方操作。通过使用$0来表示闭包的输入参数,我们可以简洁地实现这个操作。 除了数组,map函数还可以应用于字典。在字典的情况下,闭包的输入参数是键值对元组,可以通过.0和.1来访问键和值。下面是一个示例: ```swift let persons = ["John": 20, "Mary": 25, "Alice": 30] let ages = persons.map { $0.value } // ages = [20, 25, 30] ``` 在这个例子中,map函数可以提取字典中的值,并将其放入新的数组中。 总之,map函数是Swift中非常有用的一个函数,可以帮助我们遍历集合中的每个元素,并对每个元素进行转换、处理或提取。无论是数组、字典还是其他集合类型,都可以使用map函数来快速实现这些操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值