10个惊艳的Swift单行代码
几年前,一篇表述“10个Scala函数式单行代码”的文章非常受欢迎,并且随后立马出现了其他的语言版本,例如Haskell版本,Ruby版本,Groovy版本,Clojure版本,Python版本,C#版本,F#版本,CoffeeScript版本等。
我们不知道有多少人真的对这些单行代码印象深刻,但我认为,这能激励大家去了解更多有关于函数式编程的内容。
1 数组中的每个元素乘以2
特别简单,尤其是使用map解决的话。
|
1
|
(1...1024).map{$0 * 2} |
2 数组中的元素求和
虽然这里使用reduce和加号运算符,借助了加号运算符是函数这样一个事实,但解决办法是显而易见的,我们可以看到 reduce更具创意的用法。
|
1
|
(1...1024).reduce(0,combine: +) |
3 验证在字符串中是否存在指定单词
让我们使用 filter来验证tweet中是否包含选定的若干关键字中的一个:
|
1
2
3
4
|
let words = ["Swift","iOS","cocoa","OSX","tvOS"]let tweet = "This is an example tweet larking about Swift"let valid = !words.filter({tweet.containsString($0)}).isEmptyvalid //true |
更新:@oisdk提出一些更好的选择:
|
1
|
words.contains(tweet.containsString) |
方式更简洁,还有这一个:
|
1
2
3
4
5
|
tweet.characters.split(" ").lazy.map(String.init).contains(Set(words).contains) |
4 读取文件
像其他语言一样,通过简单的内置来读取文件到数组中是不可能,但我们可以结合使用 split 和 map创造一些不需要for循环的简短代码:
|
1
2
3
4
5
6
7
8
|
let path = NSBundle.mainBundle().pathForResource("test", ofType: "txt")let lines = try? String(contentsOfFile: path!).characters.split{$0 == "\n"}.map(String.init)if let lines=lines { lines[0] // O! for a Muse of fire, that would ascend lines[1] // The brightest heaven of invention! lines[2] // A kingdom for a stage, princes to act lines[3] // And monarchs to behold the swelling scene.} |
map和字符串构造函数的最后一步把我们的数组字符转换为字符串。
5 祝你生日快乐!
这将显示生日快乐歌到控制台,通过map以及范围和三元运算符的简单使用。
|
1
2
|
let name = "uraimo"(1...4).forEach{print("Happy Birthday " + (($0 == 3) ? "dear \(name)":"to You"))} |
6 过滤数组中的数字
在这种情况下,我们需要使用提供的过滤函数分区一个序列。许多语言除了拥有常用的map、flatMap、reduce、filter等,还有正好能做这件事的 partitionBy 函数,Swift如你所知没有类似的东西(NSPredicate提供的可以过滤的NSArray函数在这里不是我们所需要的)。
因此,我们可以用 partitionBy 函数扩展 SequenceType 来解决这个问题,我们将使用 partitionBy 函数来分区整型数组:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
extension SequenceType{ typealias Element = Self.Generator.Element func partitionBy(fu: (Element)->Bool)->([Element],[Element]){ var first=[Element]() var second=[Element]() for el in self { if fu(el) { first.append(el) }else{ second.append(el) } } return (first,second) }}let part = [82, 58, 76, 49, 88, 90].partitionBy{$0 < 60}part // ([58, 49], [82, 76, 88, 90]) |
不是真正的单行代码。那么,我们是否可以使用过滤器来改善它?
|
1
2
3
4
5
6
7
|
extension SequenceType{ func anotherPartitionBy(fu: (Self.Generator.Element)->Bool)->([Self.Generator.Element],[Self.Generator.Element]){ return (self.filter(fu),self.filter({!fu($0)})) }}let part2 = [82, 58, 76, 49, 88, 90].anotherPartitionBy{$0 < 60}part2 // ([58, 49], [82, 76, 88, 90]) |
稍微好了一点,但它遍历了序列两次,并且试图把它变成单行代码删除闭包功能将会导致太多重复的东西(过滤函数和数组会在两个地方使用)。
我们是否使用单个数据流建立一些能够将初始序列转换为分区元组的东西?是的,我们可以用 reduce。
|
1
2
3
4
5
|
var part3 = [82, 58, 76, 49, 88, 90].reduce( ([],[]), combine: { (a:([Int],[Int]),n:Int) -> ([Int],[Int]) in (n<60) ? (a.0+[n],a.1) : (a.0,a.1+[n])})part3 // ([58, 49], [82, 76, 88, 90]) |
我们在这里构建了包含两个分区的结果元组,一次一个元素,使用过滤函数测试初始序列中的每个元素,并根据过滤结果追加该元素到第一或第二分区数组中。
最后得到真正的单行代码,但要注意这样一个事实,即分区数组通过追加被构建,实际上会使其比前两个实施方式要慢。
7 获取并解析XML Web服务
上面的有些语言不依赖外部库,并默认提供多个选项来处理XML(例如Scala虽然笨拙但“本地”地支持XML解析成对象),但Foundation只提供了SAX解析器NSXMLParser,并且正如你可能已经猜到的那样,我们不打算使用它。
有几个替代的开源库,我们可以在这种情况下使用,其中一些用C或Objective-C编写,其他为纯Swift。
这次,我们打算使用纯Swift的AEXML:
|
1
2
3
4
5
6
7
8
9
|
let xmlDoc = try? AEXMLDocument(xmlData: NSData(contentsOfURL: NSURL(string:"https://www.ibiblio.org/xml/examples/shakespeare/hen_v.xml")!)!)if let xmlDoc=xmlDoc { var prologue = xmlDoc.root.children[6]["PROLOGUE"]["SPEECH"] prologue.children[1].stringValue // Now all the youth of England are on fire, prologue.children[2].stringValue // And silken dalliance in the wardrobe lies: prologue.children[3].stringValue // Now thrive the armourers, and honour's thought prologue.children[4].stringValue // Reigns solely in the breast of every man: prologue.children[5].stringValue // They sell the pasture now to buy the horse,} |
8 在数组中查找最小(或最大)值
我们有各种方法来找到序列中的最小和最大值,其中有 minElement 和maxElement 函数:
|
1
2
3
4
5
6
7
8
|
//Find the minimum of an array of Ints[10,-22,753,55,137,-1,-279,1034,77].sort().first[10,-22,753,55,137,-1,-279,1034,77].reduce(Int.max, combine: min)[10,-22,753,55,137,-1,-279,1034,77].minElement()//Find the maximum of an array of Ints[10,-22,753,55,137,-1,-279,1034,77].sort().last[10,-22,753,55,137,-1,-279,1034,77].reduce(Int.min, combine: max)[10,-22,753,55,137,-1,-279,1034,77].maxElement() |
9 并行处理
某些语言允许用一种简单和透明的方式启用数组对功能,例如map和flatMap的并行处理,以加快顺序和独立操作的执行。
此功能Swift中还不可用,但可以使用GCD构建:http://moreindirection.blogspot.it/2015/07/gcd-and-parallel-collections-in-swift.html
10 埃拉托斯特尼筛法
埃拉托斯特尼筛法用于查找所有的素数直到给定的上限n。
从小于n的所有整数序列开始,算法删除所有整数的倍数,直到只剩下素数。并且为了加快执行速度,我们实际上并不需要检查每个整数的倍数,我们止步于n的平方根就可以了。
根据这一定义首次执行可能是这样的:
|
1
2
3
4
|
var n = 50var primes = Set(2...n)(2...Int(sqrt(Double(n)))).forEach{primes.subtractInPlace((2*$0).stride(through:n, by:$0))}primes.sort() |
我们使用外部范围来迭代我们要检查的整数,并且对于每一个整数我们使用 stride(through:Int by:Int)计算出数字的倍数的序列。那些序列然后从Set中减去,Set用所有从2到n的整数初始化。
但正如你所看到的,为了实际移除倍数,我们使用外部可变Set,导致了附带后果。
为了消除附带后果,正如我们通常应该做的那样,我们会先计算所有序列,用倍数的单一数组来flatMap它们,并从初始Set中删除这些整数。
|
1
2
3
4
|
var sameprimes = Set(2...n)sameprimes.subtractInPlace((2...Int(sqrt(Double(n)))).flatMap{ (2*$0).stride(through:n, by:$0)})sameprimes.sort() |
方式更清洁,使用flatMap的一个很好的例子以生成扁平化的嵌套数组。
11 其他:通过解构元组交换
最后一点,并非每个人都知道的是,和其他有tuple类型的语言一样,元组可以用来执行紧凑的变量交换:
|
1
2
3
4
|
var a=1,b=2(a,b) = (b,a)a //2b //1 |
好了,正如所料,Swift和其他语言一样富有表现力。
10个惊艳的Swift单行代码的更多相关文章
- ( 转 )超级惊艳 10款HTML5动画特效推荐
今天我们要来推荐10款超级惊艳的HTML5动画特效,有一些是基于CSS3和jQuery的,比较实用,特别是前几个HTML5动画,简直酷毙了,现在将它们分享给大家,也许你能用到这些HTML5动画和jQu ...
- 分享10款效果惊艳的HTML5图片特效
在HTML5的世界里,图片特效都十分绚丽,我们在网站上也分享过很多不错的HTML5图片特效,现在我们精选10款效果惊艳的HTML5图片特效分享给大家. 1.HTML5 3D正方体旋转动画 很酷的3D特 ...
- 超级惊艳 10款HTML5动画特效推荐[转]
ylbtech_html5_demo 今天我们要来推荐 10 款超级惊艳的 HTML5 动画特效,有一些是基于 CSS3 和 jQuery 的,比较实用,特别是前几个 HTML5 动画,简直酷毙了,现 ...
- 惊艳!9个不可思议的 HTML5 Canvas 应用试验
HTML5 <canvas> 元素给网页中的视觉展示带来了革命性的变化.Canvas 能够实现各种让人惊叹的视觉效果和高效的动画,在这以前是需要 Flash 支持或者 JavaScript ...
- uperTextView-从未如此惊艳!一个超级的TextView
简介 下载:http://www.see-source.com/androidwidget/detail.html?wid=1273 欢迎使用SuperTextView,这篇文档将会向你展示如何使用这 ...
- 【Java】反射调用与面向对象结合使用产生的惊艳
缘起 我在看Spring的源码时,发现了一个隐藏的问题,就是父类方法(Method)在子类实例上的反射(Reflect)调用. 初次看到,感觉有些奇特,因为父类方法可能是抽象的或私有的,但我没有去怀疑 ...
- 奇思妙想 CSS 3D 动画 | 仅使用 CSS 能制作出多惊艳的动画?
本文将从比较多的方面详细阐述如何利用 CSS 3D 的特性,实现各类有趣.酷炫的动画效果.认真读完,你将会收获到: 了解 CSS 3D 的各种用途 激发你新的灵感,感受动画之美 对于提升 CSS 动画 ...
- 理解C# 4 dynamic(4) – 让人惊艳的Clay
Clay非常类似于ExpandoObject, 可以看做是ExpandoObject的加强版. 它们能够让我们在不需要定义类的情况下,就构建出我们想要的对象.Clay和ExpandoObject相比, ...
- 使用 HTML5 Canvas 绘制出惊艳的水滴效果
HTML5 在不久前正式成为推荐标准,标志着全新的 Web 时代已经来临.在众多 HTML5 特性中,Canvas 元素用于在网页上绘制图形,该元素标签强大之处在于可以直接在 HTML 上进行图形操作 ...
随机推荐
- HTML 上传图片实用小技巧
最近写的项目需要用的上传图片的功能但是浏览器自带的按钮样式实在是不忍直视,肯定要进行修改,网上也有很多方法(自己查....),我这里用了个取巧的方法:就是函数的间接调用 在点击btn的时候让它执行了图 ...
- 工作总结_JS_1
获取点击下的相对应的div: $('> div', this).show(); 本身同级下的相对应的div: $('>div[name=vv]', $(this).siblings(& ...
- C语言两种查找方式(分块查找,二分法)
二分法(必须要保证数据是有序排列的): 分块查找(数据有如下特点:块间有序,块内无序):
- Spring之注入的几种方式
普通注入 在配置文件里 <!-- 构造注入 --> <bean id="user1" class="entity.User"> < ...
- 开始研究unreal4了
最后一个周末了,昨天去做了许多事,算是对最近的一些整理和了结吧.早上广州下雨了,9点起来吃了早餐之后又睡了1个小时.中午吃了泡面,幸福感max.晚上煎了菜脯蛋和肉卷,拖着拉着把<旋风十一人> ...
- .NET程序反汇编JustDecompile 开源
JustDecompile是Telerik公司推出一个免费的.net反编译工具,支持插件,与Visual Studio 集成,能够创建Visual Studio project文件.JustDecom ...
- iOS开发系列—Objective-C之基础概览
概览 前面我们已经用了几章内容进行C语言介绍,当然要通过几篇文章完整的介绍C语言的知识是不太现实的,例如C语言的文件操作.内存申请等我们都没有重点介绍,当然核心知识点基本都已经提到了,后面有时间我们会 ...
- Redhat环境下编译安装Google Bazel
Redhat环境下编译安装bazel 作者:Jack47 目前Google Bazel没有提供各个操作系统下的二进制安装包,只提供源代码,需要我们自己编译安装,详情可以见我翻译的中文版Google B ...
- 人人都是 DBA(XII)查询信息收集脚本汇编
什么?有个 SQL 执行了 8 秒! 哪里出了问题?臣妾不知道啊,得找 DBA 啊. DBA 人呢?离职了!!擦!!! 程序员在无处寻求帮助时,就得想办法自救,努力让自己变成 "伪 DBA& ...
- js动态生成选项之考试系统(一)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"% ...