掌握这9段Swift代码,让你教面试官重新做人

前端之家收集整理的这篇文章主要介绍了掌握这9段Swift代码,让你教面试官重新做人前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1 将数组中每个元素的值乘以 2

第一个例子中没什么干货,我们都知道只要使用map函数就可以简单地解决问题:

let arr = (1...20).map{$0*2}
print(arr)//[2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40]

2 求一组数字的和

这个问题可以通过使用reduce方法和加号运算符解决,这是因为加号运算符实际上也是一个函数。不过这个解法是非常显而易见的,待会儿我们会看到reduce方法更具有创造力的使用。

print((1...20).reduce(0,+))//210

3 证明字符串中含有某个单词

有三种方法:其中第三种方法的split函数如何使用看这里

let words = ["Swift","iOS","cocoa","OSX","tvOS"]
let tweet = "This is an example tweet larking about Swift"
print(!words.filter({tweet.contains($0)}).isEmpty) //true
        
print(words.contains(where: tweet.contains))// true
        
let result = tweet.characters
            .split(separator: " ")
            .lazy
            .map(String.init)
            .contains(where: Set(words).contains)
print(result)// true

4 读取一个文件

和其他语言不同,Swift 不能使用内建的函数读取文件,并把每一行存放到数组中。不过我们可以结合splitmap方法写一段简短的代码,这样就无需使用for循环:

let path = Bundle.main.path(forResource: "test",ofType: "txt")
let lines = try? String(contentsOfFile: path!).characters.split{$0 == "\n"}.map(String.init)
if let lin = lines {
    print(lin)
}

5 祝你生日快乐

这段代码会将“祝你生日快乐”这首歌的歌词输出到控制台中,它在一段区间内简单的使用了map函数,同时也用到了三元运算符。

let name = "uraimo"
(1...4).forEach { print("Happy Birthday " + (($0 == 3) ? "dear \(name)":"to You")) }

Happy Birthday to You

Happy Birthday to You

Happy Birthday dear uraimo

Happy Birthday to You


6 数组过滤

假设我们需要使用一个给定的过滤函数将一个序列(sequence)分割为两部分。很多语言除了有常规的mapflatMapreducefilter函数外,还有一个partitionBy函数恰好可以完成这个需求。正如你所知,Swift 没有类似的函数(我们不想在这里使用NSArray中的函数,并通过NSPredicate实现过滤功能)。

所以,我们可以通过拓展SequenceType,并为它添加partitionBy函数解决这个问题。我们使用这个函数将整数数组分割为两部分:

extension Sequence {
    typealias Element = Self.Iterator.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}
print(part) // ([58,49],[82,90])
实际上,这不是单行代码,而且使用了命令式的解法。我们可以使用 filter 对它略作改进
extension Sequence {
    func anotherPartitionBy(fu: (Self.Iterator.Element)->Bool)->([Self.Iterator.Element],[Self.Iterator.Element]){
        return (self.filter(fu),self.filter({!fu($0)}))
    }
}
输出的结果是一样的

let part2 = [82,90].anotherPartitionBy{$0 < 60}
print(part2) // ([58,90])

这种解法略好一些,但是他遍历了序列两次。而且为了用单行代码实现,我们删除了闭合函数,这会导致很多重复的内容(过滤函数和数组会在两处被用到)。

能不能只用单个数据流就对原来的序列进行转换,把两个部分分别存入一个元组中呢?答案是是可以的,使用reduce方法

let part3 = [82,90].reduce( ([],[]),{ (a:([Int],[Int]),n:Int) -> ([Int],[Int]) in
    (n<60) ? (a.0+[n],a.1) : (a.0,a.1+[n])
})
print(part3) // ([58,90])

这里我们创建了一个用于保存结果的元组,它包含两个部分。然后依次取出原来序列中的元素,根据过滤结果将它放到第一个或第二个部分中。

我们终于用真正的单行代码解决了这个问题。不过有一点需要注意,我们使用append方法来构造两个部分的数组,所以这实际上比前两种实现慢一些。

7 找到数组中最小(或最大)的元素

我们有多种方式求出 sequence 中的最大和最小值,其中一种方式是使用minElementmaxElement函数

let aaa = [10,-22,753,55,137,-1,-279,1034,77]
//Find the minimum of an array of Ints
print(aaa.sorted().first ?? 0)//-279
print(aaa.reduce(Int.max,min))//-279
print(aaa.min() ?? 0) //-279
        
//Find the maximum of an array of Ints
print(aaa.sorted().last ?? 0)//1034
print(aaa.reduce(Int.min,max))//1034
print(aaa.max() ?? 0)//1034

8 埃拉托色尼选筛法(就是求小于N的所有质数)

古老而优秀的埃拉托色尼选筛法被用于找到所有小于给定的上限 n 的质数。

首先将所有小于 n 的整数都放入一个序列(sequence)中,这个算法会移除每个数字的倍数,直到剩下的所有数字都是质数。为了加快执行速度,我们其实不必检查每一个数字的倍数,当检查到 n 的平方根时就可以停止。

基于以上定义,最初的实现可能是这样的:

let n = 50
var primes = Set(2...n)
        
(2...Int(sqrt(Double(n)))).forEach {
    let _ = primes.subtract(stride(from: 2*$0,through: n,by: $0))
}
print(primes.sorted())

结果是: [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]

在外层的区间里,我们遍历每一个需要检查的数字。对于每一个数字,我们使用stride(through:Int by:Int)函数计算出由它的倍数构成的序列。最初,我们用所有 2 到 n 的整数构造了一个集合(Set),然后从集合中减掉每一个生成的序列中的元素。

不过正如你所见,为了真正的删除掉这些倍数,我们使用了一个外部的可变集合,这会带来副作用。

我们总是应该尝试消除副作用,所以我们先计算所有的子序列,然后调用flatMap方法将其中所有的元素展开,存放到单个数组中,最后再从原始的集合中删除这些整数。

let n = 50
var sameprimes = Set(2...n)
        
sameprimes.subtract((2...Int(sqrt(Double(n)))).flatMap{ stride(from: 2*$0,by: $0) })
print(sameprimes.sorted())
结果是: [2,47]

9 福利:使用析构交换元组中的值

和其他具有元组类型的语言一样,Swift 的元组可以被用来交换两个变量的值,代码很简洁:

var a1 = 1,b1 = 2
(a1,b1) = (b1,a1)
print(a1,b1)// 2  1

猜你在找的Swift相关文章