[Swift]以函數式編程的方式使用字符串中的Ranges

原文:Swift: Using String Ranges The Functional Way編程

幾周以前,我介紹了『Swift中如何使用Range截取字符串』。那時,Swift中使用Range爲何如此艱難讓人迷惑不解,可是至少咱們找到一種能夠工做的使用方法。
swift

然而,當我在過去幾周學習了許多函數式編程的知識以後,突然意識到,Swift中的Range之因此這麼難用是爲了引導咱們以一種更加具象的方式使用它--具體來講就是相似於函數式編程的方式。app

經過觀看edX FP101x課程,我學到的第一條知識就是head和tail的概念。事實上,最初的一節課程中整整花費了五分鐘的時間來介紹headtail的概念,而且在以後的課程中也一直都有說起到這兩個概念。概念自己很是簡單: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中都有體現。設計

相關文章
相關標籤/搜索