Swift函数式编程体验

银行卡校验算法(ISO/IEC 7812)蛮简单,轻松撸完。然后又用Swift函数式编程的方法优化了之前的实现,更加喜欢Swift了。

Luhn算法通过函数式编程的Swift实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private func LuhnAlgorithm(digits:String) ->String {

let checksum = digits.characters
.reverse()
.flatMap{ Int(String($0)) }
.enumerate()
.reduce(0) {
let indexIsOdd = $1.0 % 2 == 1
guard indexIsOdd else { return $0 + ($1.1 == 9 ? 9 : $1.1 * 2 % 9) }
return $0 + $1.1
} % 10

return checksum == 0 ? String(checksum) : String(10 - checksum)
}

这个简短的函数已经展示了函数式编程的魅力——实在是太精炼了!
通过函数式编程实现,几乎比原来过程式编程的实现方式减少了一半以上的代码行数,非常精炼,没有任何冗余代码。
上面代码中的flatMap()其实就是map()方法,只不过是Swift里面的一种特殊实现。

同样的,通过函数式编程实现中国大陆身份证号码校验算法,也异常精炼:

1
2
3
4
5
6
7
8
9
10
private func computeCheckSum(idCardNo:String) ->String {

let R:[Int] = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
let checksumMap:[String] = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
let sum = R.enumerate().reduce(0) {
return $0 + Int(String(idCardNo[$1.0]))! * $1.1
}

return checksumMap[sum % 11]
}

我接触函数式编程比较晚,第一次接触到map()reduce()filter()这样的高级函数是在工作后学习Python时才了解到的,Swift这种新语言必然少不了这些高级函数,可谓是不知道比Objective-C高到哪里去了,所有的OC程序员都应该学习一个。

大量函数式代码会使算法变得越发的晦涩难读,其实上面的算法不了解的人肯定会觉得晦涩,我之所以觉得精炼美妙,是因为我已经先用过程式的代码实现了一遍,已经理解了算法细节。所以函数式编程用在合适的地方就好,不要滥用。

本质上说,函数式编程过程式编程是两种完全不同的思维方式,后者更符合人类思维方式一些。以后可以在写完过程式的代码,再思考下用函数式该怎么表达,就当是思维体操了。

完整代码在这里:

[1] 银行卡校验算法(ISO/IEC 7812)

[2] 中国大陆身份证校验算法