10个惊艳的Swift单行代码

2020-01-08 23:18:35王旭


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])

不是真正的单行代码。那么,我们是否可以使用过滤器来改善它?


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])

我们在这里构建了包含两个分区的结果元组,一次一个元素,使用过滤函数测试初始序列中的每个元素,并根据过滤结果追加该元素到第一或第二分区数组中。

最后得到真正的单行代码,但要注意这样一个事实,即分区数组通过追加被构建,实际上会使其比前两个实施方式要慢。

7 获取并解析XML Web服务

上面的有些语言不依赖外部库,并默认提供多个选项来处理XML(例如Scala虽然笨拙但“本地”地支持XML解析成对象),但Foundation只提供了SAX解析器NSXMLParser,并且正如你可能已经猜到的那样,我们不打算使用它。

有几个替代的开源库,我们可以在这种情况下使用,其中一些用C或Objective-C编写,其他为纯Swift。

这次,我们打算使用纯Swift的AEXML:


let xmlDoc = try? AEXMLDocument(xmlData: NSData(contentsOfURL: NSURL(string:"https://www.easck.com/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,
}