給swift程式猿留下深刻印象的10個Swift代碼

来源:http://www.cnblogs.com/salam/archive/2016/04/22/5419772.html
-Advertisement-
Play Games

通過使用單行代碼完成同樣的 10 個練習,我們來看看 Swift 和其他語言之間的較量。 將數組中每個元素的值乘以 2 使用map來實現 代碼簡單明瞭地完成了數組元素乘2 求一組數字的和 這個問題可以通過使用 reduce 方法和加號運算符解決,這是因為加號運算符實際上也是一個函數。不過這個解法是非 ...


通過使用單行代碼完成同樣的 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)分割為兩部分。很多語言除了有常規的mapflatMapreducefilter 等函數外,還有一個 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 和其他語言一樣富有表現力。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 作者l800891,源碼The-Red-Button-Swift,Swift代碼實現的自虐小游戲The-Red-Button-Swift,按鈕顏色會不停變換,按到藍色加分,按到紅色游戲結束。 靈感來自美國App Store上受歡迎游戲Don't tap the red button 源碼下載:htt ...
  • <ignore_js_op> 源碼下載:http://code.662p.com/view/13343.html 源碼下載:http://code.662p.com/view/13343.html 源碼下載:http://code.662p.com/view/13343.html 作者ymcao,源 ...
  • BingoWorld介紹BingoWorld是一款IT閱讀學習類的開源軟體,在不久的將來會擁有豐富的學習內容,包含Android、iOS技術文章和相關面試題等。推薦您也來用用來看看,您也可以發佈自己的Bingo鏈接文章。該APP是通過新浪微博登錄的,為防止大家clone下來後無法編譯和不能正常使用微 ...
  • 作者nuptboyzhb,源碼newplanegame,新版飛機大戰是一款以真實戰機為模板的飛行射擊類游戲,體驗新穎,玩法炫酷。一樣的經典,不一樣的體驗。飛機模型基於目前的主流戰機:包括美國F16,F22,法國幻影2000等機型模型,真實機型任你選。 源碼下載:http://code.662p.co ...
  • Fragment 源碼:http://www.jinhusns.com/Products/Download/?type=xcj Android是在Android 3.0 (API level 11)開始引入Fragment的。 可以把Fragment想成Activity中的模塊,這個模塊有自己的佈局 ...
  • 一,效果圖。 二,工程圖。 三,代碼。 RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController : UIViewController <UIScrollViewDelegate,UITableViewDel ...
  • 關於方法前的 + - 符號 MyClass.alloc().init(foo.bar()).autorelease(); ...
  • 很多人一提到Binder就說代理模式,人云亦云的多,能理解精髓的少。 本篇文章就從設計角度分析一下java層BInder的設計目標,以及設計思路,設計缺陷,從而駕馭它。 對於【邦德兒】的理解, 從通信的角度來看,就是一種通信方式而已,與socket沒有任何區別。客戶端transact,服務端onTr ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...