原文:Swift: Using String Ranges The Functional Way編程
幾周以前,我介紹了『Swift中如何使用Range截取字符串』。那時,Swift中使用Range爲何如此艱難讓人迷惑不解,可是至少咱們找到一種能夠工做的使用方法。
swift
然而,當我在過去幾周學習了許多函數式編程的知識以後,突然意識到,Swift中的Range之因此這麼難用是爲了引導咱們以一種更加具象的方式使用它--具體來講就是相似於函數式編程的方式。app
經過觀看edX FP101x課程,我學到的第一條知識就是head和tail的概念。事實上,最初的一節課程中整整花費了五分鐘的時間來介紹head和tail的概念,而且在以後的課程中也一直都有說起到這兩個概念。概念自己很是簡單:head是list的第一個元素,tail是除去list中第一個元素之外的其餘元素組成的list。函數式編程
head[1,2,3,4,5] // 1 tail[1,2,3,4,5] // [2,3,4,5]
在函數式編程中,甚少使用經典的for循環處理問題,取而代之的是使用head、tail和遞歸的方式處理list中的元素的操做。
函數
下面咱們來看一個具體例子:獲取一個單詞中前x位的字符。若是不考慮使用Swift中的Ranges(由於確實不易用),你可能會用下面的方式實現:
學習
func getSubstringUpToIndex(index: Int, fromString str: String) -> String { var substring = "" for (i, letter) in enumerate(str) { substring.append(letter) if i == index - 1 { break } } return substring } getSubstringUpToIndex(5, fromString: "Hello, NatashaTheRobot") // Hello
如今來看看函數式編程的思想,使用head、tail和遞歸如何實現:
spa
func getSubstringUpToIndex(index: Int, fromString str: String) -> String { let (head, tail) = (str[str.startIndex], dropFirst(str)) if index == 1 { return String(head) } return String(head) + getSubstringUpToIndex(index - 1, fromString: tail) } getSubstringUpToIndex(5, fromString: "Hello, NatashaTheRobot") // Hello
看過上面的例子,我想你們對於Swift爲什麼設計這麼難用的Ranges、startIndex、endIndex有了一些本身的認識。.net
對於上面的例子,也可使用我在『Swift中如何使用Range截取字符串』中描述的方法,可是經過上面介紹的採用函數式的解決方案,取代for循環的解決方案,咱們能夠開始更多的思考如何使用函數式編程的思想來解決問題。畢竟,這種關注頭和尾的方式(同時沒有更簡單的方式來解決問題)在不少Swift的API中都有體現。設計