Swift中的函数式编程

如果我们查找有关函数式编程的文章,则其中大多数都在谈论高级函数式编程,例如副作用,无状态,不变性或monad之类的内容 ,而其他基本示例(例如map的工作方式)则太简单了,但是在这里试图通过使用Swift中的示例来展示函数式编程的实用方面。

这篇文章的第一部分将为您简要概述函数式编程和基本定义。 示例部分显示了如何以功能样式编写命令性非功能代码。

高阶函数

函数式编程语言的第一个显着区别是,可以将函数分配给值并传递给其他函数。 这就是为什么他们被称为头等公民。 当您说一种语言具有一流的功能时,这意味着它将一种功能视为值,您可以将一个功能分配给一个变量,或者将其传递。 一流的功能被视为一个对象。

有一个更高层次的功能。 它们接受一个或多个函数作为参数或返回其他函数。 高阶函数是可以在其他函数上使用的函数,即它们将函数作为参数,也可以返回一个函数。

映射,过滤,缩小

Map是著名的高阶函数之一。 Map在数组(更确切地说是集合)上工作,它接受一个函数(称为transform)作为参数,并将此transform函数应用于每个元素,并返回结果数组,作为“ transformed”元素的新数组。

使用map有一些优点:它更短并且需要更少的代码更少的错误空间 ,更重要的是它更干净

假设我们有一个字符串数组,要计算每个字符,我们必须1.遍历该数组,2.获取每个元素的计数,3.将其追加到新数组中:

  let houses = ["Stark", " Baratheon ", " Targaryen ", "L annister "] 
  var letterCounts:[Int] = [] 
用于房屋{
letterCounts.append(item.count)
}
  print(letterCounts) // [5, 9, 9, 9] 5,9,9,9 // [5, 9, 9, 9] 

显然,功能性方法更为简洁:

 let letterCounts = houses.map { $0.count } // [5, 9, 9, 9] 

Filter接受一个函数includeElement ,遍历数组并返回一个仅包含那些符合此条件的元素的数组。 给定的闭包采用该元素并返回Bool值,该值指示该元素是否与条件匹配。 其签名如下所示:

  func filter(_ includeElement:(Element)-> Bool)-> [Element] 

假设我们有一个包含一些质数的数组,我们想复制那些比理想平方小一个的数。 命令式解决方案很容易,只需查看质数数组并检查它是否是一个完美的平方(与n-1的完美平方n的按位与总是为0):

 让素数:[Int] = [2,3,5,7,11,11,13,17,...,79,83,89,97] 
  var mersenne:[Int] = [] 
对于素数为p的素数,其中Int(p)&Int(p + 1)== 0 {
mersenne.append(p)
}
// mersenne [3,7,31]

您可以使用filter在一行中缩短整个for循环:

  let mersenne = primes.filter {Int($ 0)&Int($ 0 + 1)== 0} 

Filter仅返回可以满足关闭条件的元素组成的数组。

降低

Reduce将所有元素组合为一个值(例如,将所有元素加总)。 它对一个累加器和数组中的每个元素应用一个函数,以将其减少为单个值。 它具有两个参数,即初始值和用于将累积值与元素组合的函数。 在总结数组元素的情况下,我们可以将其写为:

  let sum = array.reduce(0){总计,总计num + num} 

或仅传递运算符array.reduce(0, +)因为运算符是函数。