给swift程序猿留下深刻印象的10个Swift代码
通过使用单行代码完成同样的 10 个练习,我们来看看 Swift 和其他语言之间的较量。
将数组中每个元素的值乘以 2
使用map来实现
var arr = [1,2,3,4];
var newArr = arr.map{$0*2}
for item in newArr
{
print(item)
}
代码简单明了地完成了数组元素乘2
求一组数字的和
这个问题可以通过使用 reduce
方法和加号运算符解决,这是因为加号运算符实际上也是一个函数。不过这个解法是非常显而易见的,待会儿我们会看到 reduce
方法更具有创造力的使用。
var arr = [1,2,3,4]; let sum = arr.reduce(0, combine: +) print(sum)
检索字符串中含有某个单词
我们使用 contains方法判断一个字符串中是否至少含有一个被选中的关键字:
let arr = ["ForrestWoo","Swift1"]
let str = "My name is ForrestWoo,I am learning Swift"
let query = arr.contains(str.containsString)
print(query)
读取一个文件
let path = NSBundle.mainBundle().pathForResource("filter", ofType: "rtf")
let lines = try? String(contentsOfFile: path!).characters.split{$0 == "\n"}.map(String.init)
for item in lines! {
print(item)
}
祝你生日快乐
let name = "Forrest"
(1...4).forEach{print("Happy Birthday " + (($0 == 3) ? "dear \(name)":"to You"))}
这段代码会将“祝你生日快乐”这首歌的歌词输出到控制台中,它在一段区间内简单的使用了 map
函数,同时也用到了三元运算符。
数组过滤
假设我们需要使用一个给定的过滤函数将一个序列(sequence)分割为两部分。很多语言除了有常规的map
,flatMap
,reduce
,filter
等函数外,还有一个 partitionBy
函数恰好可以完成这个需求。正如你所知,Swift 没有类似的函数(我们不想在这里使用 NSArray 中的函数,并通过NSPredicate 实现过滤功能)。
所以,我们可以通过拓展 SequenceType
,并为它添加 partitionBy
函数来解决这个问题。我们使用这个函数将整数数组分割为两部分:
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])
实际上,这不是单行代码,而且使用了命令式的解法。能不能使用 filter
对它略作改进呢?
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
方法:
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])
这里我们创建了一个用于保存结果的元组,它包含两个部分。然后依次取出原来序列中的元素,根据过滤结果将它放到第一个或第二个部分中。
我们终于用真正的单行代码解决了这个问题。不过有一点需要注意,我们使用 append
方法来构造两个部分的数组,所以这实际上比前两种实现慢一些。
获取并解析 XML 格式的网络服务
上述的某些语言不需要依赖外部的库,而且默认有不止一种方案可以处理 XML 格式的数据(比如 Scala 自身就可以将 XML 解析成对象,尽管实现方法比较笨拙),但是 (Swift 的)Foundation 库仅提供了 SAX 解析器,叫做 NSXMLParser。你也许已经猜到了:我们不打算使用这个。
在这种情况下,我们可以选择一些开源的库。这些库有的用 C 实现,有的用 Objective-C 实现,还有的是纯 Swift 实现。
这次,我们打算使用纯 Swift 实现的库:AEXML:
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,
}
找到数组中最小(或最大)的元素
我们有多种方式求出 sequence 中的最大和最小值,其中一种方式是使用 minElement
和maxElement
函数:
//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()
并行处理
某些语言支持用简单透明的方式允许对序列的并行处理,比如使用 map
和 flatMap
这样的函数。这使用了底层的线程池,可以加速多个依次执行但又彼此独立的操作。
Swift 还不具备这样的特性,但我们可以用 GCD 实现:
http://moreindirection.blogspot.it/2015/07/gcd-and-parallel-collections-in-swift.html
埃拉托色尼选筛法
古老而优秀的埃拉托色尼选筛法被用于找到所有小于给定的上限 n 的质数。
首先将所有小于 n 的整数都放入一个序列(sequence)中,这个算法会移除每个数字的倍数,直到剩下的所有数字都是质数。为了加快执行速度,我们其实不必检查每一个数字的倍数,当检查到 n 的平方根时就可以停止。
基于以上定义,最初的实现可能是这样的:
var n = 50
var 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)
函数计算出由它的倍数构成的序列。最初,我们用所有 2 到 n 的整数构造了一个集合(Set),然后从集合中减掉每一个生成的序列中的元素。
不过正如你所见,为了真正的删除掉这些倍数,我们使用了一个外部的可变集合,这会带来副作用。
我们总是应该尝试消除副作用,所以我们先计算所有的子序列,然后调用 flatMap
方法将其中所有的元素展开,存放到单个数组中,最后再从原始的集合中删除这些整数。
var sameprimes = Set(2...n) sameprimes.subtractInPlace((2...Int(sqrt(Double(n))))
.flatMap{ (2*$0).stride(through:n, by:$0)})
sameprimes.sort()
使用析构交换元组中的值
既然是福利,自然并非每个人都知道这一点。和其他具有元组类型的语言一样,Swift 的元组可以被用来交换两个变量的值,代码很简洁:
var a=1,b=2 (a,b) = (b,a)
a //2
b //1
以上就是全部内容,正如我们预料的那样,Swift 和其他语言一样富有表现力。
给swift程序猿留下深刻印象的10个Swift代码的更多相关文章
- 程序猿爱情表白专用html5动画网页的代码
程序猿爱情表白专用html5动画网页的代码 下载地址:源代码 程序员表白专用的html5动画特效网页,真的挺羡慕创作者的水平,有这水平能够把爱表白给想表白的人,不要以为那些鲜花是用 的图片.你会发如今 ...
- C#程序员经常用到的10个实用代码片段
1 读取操作系统和CLR的版本 OperatingSystem os = System.Environment.OSVersion; Console.WriteLine(“Platform: {}”, ...
- C#程序员经常用到的10个实用代码片段 - 操作系统
原文地址 如果你是一个C#程序员,那么本文介绍的10个C#常用代码片段一定会给你带来帮助,从底层的资源操作,到上层的UI应用,这些代码也许能给你的开发节省不少时间.以下是原文: 1 读取操作系统和C ...
- [Swift实际操作]八、实用进阶-(10)使用Swift创建一个二叉树BinaryTreeNode
1.二叉树的特点: (1).每个节点最多有两个子树(2).左子树和右子树是有顺序的,次序不能颠倒(3).即使某节点只有一个子树,也要区分左右子树 2.二叉查找树(Binary Search Tree) ...
- 程序bug导致了天大的损失,要枪毙程序猿吗?[ZZ]
来自猫扑:程序bug导致了天大的损失,要枪毙程序猿吗? 0 引言 年会上Review 源代码算什么? 法庭上 Review code 才带劲..... 2015年9月3日,随着东京最高法院驳回瑞穗证券 ...
- 疯狂Java学习笔记(72)-----------大话程序猿面试
大话程序猿面试 10个我最喜欢问程序猿的面试问题 程序猿面试不全然指南 10个经典的C语言面试基础算法及代码 程序猿的10大成功面试技巧 程序猿选择公司的8个标准 编程开发 8个值得关注的PHP安全函 ...
- 黑马程序猿_Java 代理机制学习总结
-------<a href="http://www.itheima.com/"">android培训</a>.<a href=" ...
- Swift学习笔记(十五)——程序猿浪漫之用Swift+Unicode说我爱你
程序猿经常被觉得是呆板.宅,不解风情的一帮人.可是有时候.我们也能够使用自己的拿手本领来表现我们的浪漫. 因为Swift语言是支持Unicode编码的,而Unicode最新已经支持emoji(绘文字) ...
- 回答阿里社招面试如何准备,顺便谈谈对于Java程序猿学习当中各个阶段的建议
引言 其实本来真的没打算写这篇文章,主要是LZ得记忆力不是很好,不像一些记忆力强的人,面试完以后,几乎能把自己和面试官的对话都给记下来.LZ自己当初面试完以后,除了记住一些聊过的知识点以外,具体的内容 ...
随机推荐
- CodeIgniter2.2.0-在控制器里调用load失败报错的问题
报错如下: hello A PHP Error was encountered Severity: Notice Message: Undefined property: Test::$load Fi ...
- [.NET领域驱动设计实战系列]专题四:前期准备之工作单元模式(Unit Of Work)
一.前言 在前一专题中介绍了规约模式的实现,然后在仓储实现中,经常会涉及工作单元模式的实现.然而,在我的网上书店案例中也将引入工作单元模式,所以本专题将详细介绍下该模式,为后面案例的实现做一个铺垫. ...
- 在ASP.NET WebAPI 中使用缓存【Redis】
初步看了下CacheCow与OutputCache,感觉还是CacheOutput比较符合自己的要求,使用也很简单 PM>Install-Package Strathweb.CacheOutpu ...
- Viewbox在UWP开发中的应用
Windows 8.1 与Windows Phone 8.1的UAP应用,终于在Windows 10上统一到了UWP之下.原来3个不同的project也变为一个.没有了2套xaml页面,我们需要用同一 ...
- Java虚拟机8:虚拟机性能监控与故障处理工具
前言 定位系统问题的时候,知识.经验是基础,数据是依据,工具是运用知识处理数据的手段.这里说的数据包括:运行日志.异常堆栈.GC日志.线程快照.堆转储快照等.经常使用适当的虚拟机监控和分析的工具可以加 ...
- WPF,Silverlight与XAML读书笔记第四十八 - Silverlight网络与通讯
说明:本系列基本上是<WPF揭秘>的读书笔记.在结构安排与文章内容上参照<WPF揭秘>的编排,对内容进行了总结并加入一些个人理解. 这一部分我们重点讨论下Silverlight ...
- 《kali linux 渗透测试初级教程》免费下载
Kali Linux系列教程是在51cto上售卖的入门教程,售价100元.每天都有很多网友找我要全部教程,也有人偷偷的录制了教程.索性公开出来,如果您觉得还可以的话,希望可以选择发个小红包或者转发 获 ...
- web前端工程师在移动互联网时代里的地位问题
支付宝十周年推出了一个新产品:支付宝的十年账单,我也赶个时髦查看了一下我的支付宝十年账单,哎,感慨自己真是太屌丝了,不过这只是说明我使用淘宝少了,当我大规模网上购物时候,我很讨厌慢速的快递,所以我大部 ...
- MYSQL分页存储过程及事务处理
最近给客户做的一小系统是SQLSERVER的数据库,因为特殊原因要切换到MYSQL上去,切换数据库确实让人头疼的,SQLSERVER和MYSQL的存储过程还是有很大差别的,下面是我做切换时转换的MYS ...
- 看stackoverflow大牛如何回答何时在ASP.NET中使用异步控制器?
转载自博客园:http://farb.cnblogs.com/ 今天无意中看到stackoverflow上一个很好的问答,个人觉得很有价值,所以翻译过来和大家共享!希望大家能相互交流. 在ASP.NE ...