原文出处:http://www.cocoachina.com/swift/20160429/16051.html
几年前,一篇表述“10个Scala函数式单行代码”的文章非常受欢迎,并且随后立马出现了其他的语言版本,例如Haskell版本,Ruby版本,Groovy版本,Clojure版本,Python版本,C#版本,F#版本,CoffeeScript版本等。
我们不知道有多少人真的对这些单行代码印象深刻,但我认为,这能激励大家去了解更多有关于函数式编程的内容。
1 数组中的每个元素乘以2
特别简单,尤其是使用map解决的话。
1
|
(1...1024).map{$0*2}
|
2 数组中的元素求和
虽然这里使用reduce和加号运算符,借助了加号运算符是函数这样一个事实,但解决办法是显而易见的,我们可以看到 reduce更具创意的用法。
3 验证在字符串中是否存在指定单词
让我们使用 filter来验证tweet中是否包含选定的若干关键字中的一个:
letwords=[
"Swift"
,
"iOS"
"cocoa"
"OSX"
"tvOS"
]
lettweet=
"ThisisanexampletweetlarkingaboutSwift"
letvalid=!words.filter({tweet.containsstring($0)}).isEmpty
valid
//true
|
更新:@oisdk提出一些更好的选择:
方式更简洁,还有这一个:
tweet.characters
.split(
""
)
.lazy
.map(String.init)
.contains(Set(words).contains)
|
4 读取文件
像其他语言一样,通过简单的内置来读取文件到数组中是不可能,但我们可以结合使用 split 和 map创造一些不需要for循环的简短代码:
letpath=NSBundle.mainBundle().pathForResource(
"test"
ottom:auto!important; float:none!important; height:auto!important; left:auto!important; line-height:1.1em!important; outline:0px!important; overflow:visible!important; position:static!important; right:auto!important; top:auto!important; vertical-align:baseline!important; width:auto!important; font-family:Consolas,ofType:
"txt"
)
lines[1]
//Thebrightestheavenofinvention!
lines[2]
//Akingdomforastage,princestoact
lines[3]
//Andmonarchstobeholdtheswellingscene.
}
|
map和字符串构造函数的最后一步把我们的数组字符转换为字符串。
5 祝你生日快乐!
这将显示生日快乐歌到控制台,通过map以及范围和三元运算符的简单使用。
letname=
"uraimo"
(1...4).forEach{print(
"HappyBirthday"
+(($0==3)?
"dear\(name)"
:
"toYou"
))}
|
6 过滤数组中的数字
在这种情况下,我们需要使用提供的过滤函数分区一个序列。许多语言除了拥有常用的map、flatMap、reduce、filter等,还有正好能做这件事的 partitionBy 函数,Swift如你所知没有类似的东西(nspredicate提供的可以过滤的NSArray函数在这里不是我们所需要的)。
因此,我们可以用 partitionBy 函数扩展 SequenceType 来解决这个问题,我们将使用 partitionBy 函数来分区整型数组:
extensionSequenceType{
typealiasElement=Self.Generator.Element
funcpartitionBy(fu:(Element)->Bool)->([Element],[Element]){
second=[Element]()
for
el
in
self{
fu(el){
first.append(el)
}
else
{
second.append(el)
}
}
return
(first,second)
}
}
letpart=[82,76,49,88,90].partitionBy{$0<60}
part
//([58,49],[82,90])
|
不是真正的单行代码。那么,我们是否可以使用过滤器来改善它?
funcanotherPartitionBy(fu:(Self.Generator.Element)->Bool)->([Self.Generator.Element],[Self.Generator.Element]){
(self.filter(fu),self.filter({!fu($0)}))
}
}
letpart2=[82,90].anotherPartitionBy{$0<60}
part2
稍微好了一点,但它遍历了序列两次,并且试图把它变成单行代码删除闭包功能将会导致太多重复的东西(过滤函数和数组会在两个地方使用)。
|