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

原文:Swift: Using String Ranges The Functional Way

几周之前,我介绍了『Swift中如何使用Range截取字符串』。那时,Swift中使用Range为什么如此艰难让人疑惑不解,但是至少我们找到一种可以工作的使用方法。

然而,当我在过去几周学习了许多函数式编程的知识之后,忽然意识到,Swift中的Range之所以这么难用是为了引导我们以一种更加具象的方式使用它--具体来说就是类似于函数式编程的方式。

通过观看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和递归如何实现:

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有了一些自己的认识。

对于上面的例子,也可以使用我在『Swift中如何使用Range截取字符串』中描述的方法,但是通过上面介绍的采用函数式的解决方案,取代for循环的解决方案,我们可以开始更多的思考如何使用函数式编程的思想来解决问题。毕竟,这种关注头和尾的方式(同时没有更简单的方式来解决问题)在很多Swift的API中都有体现。

时间: 2024-10-25 09:17:31

[Swift]以函数式编程的方式使用字符串中的Ranges的相关文章

【编程题目】在一个字符串中找到第一个只出现一次的字符。如输入 abaccdeff,则输出 b。

第 17 题(字符串):题目:在一个字符串中找到第一个只出现一次的字符.如输入 abaccdeff,则输出 b. 思路:此题非常容易. 最开始是想开辟一块空间存储每个字符出现的次数. 但转念一想,似乎没有必要. 对每一个字符,都依次和后面的比较,若出现了两次,则检查下一个字符,遇到只出现一次的,直接输出就好了. /* 第 17 题(字符串): 题目:在一个字符串中找到第一个只出现一次的字符.如输入 abaccdeff,则输出 b. 分析:这道题是 2006 年 google 的一道笔试题. */

【编程题目】在字符串中删除特定的字符

63.在字符串中删除特定的字符(字符串).题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符.例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”. 我的思路:先扫描第一个字符串,判断是否是第二的字符串的字符,是则跳过,记录跳过多少个,后面的不被删除的就前移. /* 63.在字符串中删除特定的字符(字符串). 题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符. 例如,输入”They are s

swift之函数式编程(二)------- Thinking Functionally

本文的主要内容来自<Functional Programming in Swift>这本书,有点所谓的观后总结 在本书的Introduction章中: we will try to focus on some of the qualities that we believe well-designed functional programs in Swift should exhibit: 1. Modulatity[模块化] 2. A Careful Treatment of Mutable

swift之函数式编程(四)

文章内容来自<Functional Programing in Swift>,具体内容请到书中查阅 Map, Filter, Reduce Functions that take functions as arguments are sometimes called higher- order functions. higher-order function(高阶函数)就是说函数可以作为另一个函数的参数. 在本章,我们将介绍一下swift标准库中在数组方面的一些相关的高阶函数,先介绍一些比较普

swift 之函数式编程(一)

1. 什么是函数式编程? 函数式编程是阿隆佐思想的在现实世界中的实现, 它将电脑运算视为数学上的函数计算,并且避免使用程序状态以及异变物件. 函数式编程的最重要基础是λ演算.而且λ演算的函數可以接受函數當作輸入(引數)和輸出(傳出值),函數式編程更加強調程序执行的结果而非执行的过程,倡导利用若干简单的执行单元让计算结果不断渐进,逐层推导复杂的运算,而不是设计一个复杂的执行过程.函数式编程的杀手锏正是当今世界上日益增长的并行性编程和元数据编程趋势.其主要思想就是把运算过程尽量写成一系列嵌套的函数调

C#编程入门--将指定字符串中的汉字转换为拼音缩写,其中非汉字保留为原字符

将指定字符串中的汉字转换为拼音缩写,其中非汉字保留为原字符 #region 将指定字符串中的汉字转换为拼音缩写,其中非汉字保留为原字符 /// <summary> /// 将指定字符串中的汉字转换为拼音缩写,其中非汉字保留为原字符 /// </summary> /// <param name="text"></param> /// <returns></returns> public static string G

swift之函数式编程(三)

文章来源于<Functional Programing in Swift>,本系列仅仅是观后概括的一些内容 Wrapping Core Image 上一篇文章我们介绍了 高阶函数并且展示了函数是如何作为参数传递给其他函数.在本章中,我们将展示如何使用高阶函数对已有的 面向对象的API 进行函数式包装. Core Image 是一个非常强大的图形处理的框架,但有些时候 它的API的使用有点笨重.CoreImage的API是松散类型—— image filters are configured u

python进阶一(函数式编程)【2-6 python中闭包】

python中闭包 在函数内部定义的函数和外部定义的函数是一样的,只是他们无法被外部访问: def g(): print 'g()...' def f(): print 'f()...' return g 将 g 的定义移入函数 f 内部,防止其他代码调用 g: 1 def f(): 2 print 'f()...' 3 def g(): 4 print 'g()...' 5 return g 但是,考察上一小节定义的 calc_sum 函数: 1 def calc_sum(lst): 2 de

python进阶一(函数式编程)【1-9 python中的偏函数】

python中偏函数 当一个函数有很多参数时,调用者就需要提供多个参数.如果减少参数个数,就可以简化调用者的负担. 比如,int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换: >>> int('12345') 12345 但int()函数还提供额外的base参数,默认值为10.如果传入base参数,就可以做 N 进制的转换: 1 >>> int('12345', base=8) 2 5349 3 >>> int('1