Skip to content

Instantly share code, notes, and snippets.

@gitbricho
Last active August 19, 2016 09:51
Show Gist options
  • Save gitbricho/a6165415241355729636 to your computer and use it in GitHub Desktop.
Save gitbricho/a6165415241355729636 to your computer and use it in GitHub Desktop.
swift:closure
import UIKit
//## シンタックス: {(引数リスト) -> (戻り値) in 文}
//# 変数にクロージャを代入
//例1 {() -> () }
var v引数無し戻り値無し: ()->() = {
print("引数無し戻り値無しのクロージャ")
}
v引数無し戻り値無し() //"引数無し戻り値無しのクロージャ"
//例2 {() -> (戻り値)}
var v引数無し戻り値有り: ()->(String) = {
return "引数無し戻り値有りのクロージャ"
}
print(v引数無し戻り値有り()) //"引数無し戻り値有りのクロージャ"
//例3 {(引数) -> (戻り値)}:
var v引数有り戻り値有り: (String) -> (String) = {
引数 -> String in
return "<\(引数)>"
}
print(v引数有り戻り値有り("Tom")) //"<Tom>"
//例4 関数を返すクロージャ {(Int) -> (()->Int)}
func f加算関数作成(加算数 関数増分: Int) -> (() -> Int) {
var 合計 = 0
//引数無し、戻り値がIntの関数:
//現在の合計に加算数を足して合計を返す
func f加算関数() -> Int {
合計 += 関数増分 //ローカル引数名を使用
return 合計
}
return f加算関数
}
//上記の関数を使って5を加算する関数を作成
let l5加算関数 = f加算関数作成(加算数: 5) //外部引数名を使用
l5加算関数() //5
l5加算関数() //10
l5加算関数() //15
//## クロージャーは参照型
let l別の5加算関数 = l5加算関数
l別の5加算関数() //20
import Foundation
//## クロージャを引数に取るメソッド
//# 配列のsortメソッドは、引数として
// 要素の大小比較を行う関数|クロージャを取る
// update: 16/06/15
//let lよみa = ["おおた", "くらた", "きむら", "ささき", "あいだ"]
var vよみa = ["おおた", "くらた", "きむら", "ささき", "あいだ"]
// 比較関数(配列の2つの要素を比較)// update: 16/06/15
func f逆順(s1: String, s2: String) -> Bool {
return s1 > s2
}
//(--- Swift3 ---) update: 16/06/15
//lよみa.sort(f逆順) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: f逆順) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
vよみa.sort(by: f逆順) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
vよみa.sort() //["あいだ", "おおた", "きむら", "くらた", "ささき"]
// 比較のためのクロージャ{(String,String) -> Bool in}を渡す
//(--- Swift3 ---) update: 16/06/15
//var v逆順配列 = lよみa.sort(
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore:{ (s1: String, s2: String) -> Bool in return s1 > s2 })
vよみa.sort(by: { (s1: String, s2: String) -> Bool in return s1 > s2 })
print(vよみa) //結果:["ささき", "くらた", "きむら", "おおた", "あいだ"]
// (型推論: 推論できる場合は型注釈を省略)
//(--- Swift3 ---) update: 16/06/15
//v逆順配列 = lよみa.sort({s1, s2 in return s1 < s2}) //昇順指定
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: {s1, s2 in return s1 < s2}) //昇順指定
vよみa.sort(by: {s1, s2 in return s1 < s2}) //昇順指定
print(vよみa) //結果:["あいだ", "おおた", "きむら", "くらた", "ささき"]
// (単一式のクロージャの場合の戻り値: return の省略)
//(--- Swift3 ---) update: 16/06/15
//v逆順配列 = lよみa.sort({s1, s2 in s1 > s2})
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: {s1, s2 in s1 > s2})
vよみa.sort(by: {s1, s2 in s1 > s2})
print(vよみa) //結果:["ささき", "くらた", "きむら", "おおた", "あいだ"]
// (引数リストの省略)
//(--- Swift3 ---) update: 16/06/15
//v逆順配列 = lよみa.sort({$0 > $1}) //["ささき", "くらた", "きむら", "おおた", "あいだ
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: {$0 > $1}) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
vよみa.sort(by: {$0 > $1}) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
// (オペレータ関数)
//(--- Swift3 ---) update: 16/06/15
//v逆順配列 = lよみa.sort(>) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: >) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
vよみa.sort(by: >) //["ささき", "くらた", "きむら", "おおた", "あいだ"]
//(--- Swift3 ---) update: 16/06/15
//var v昇順配列 = lよみa.sort(<) //["あいだ", "おおた", "きむら", "くらた", "ささき"]
//(--- Swift3 beta6---) update: 16/08/18
//vよみa.sort(isOrderedBefore: <) //["あいだ", "おおた", "きむら", "くらた", "ささき"]
vよみa.sort(by: <) //["あいだ", "おおた", "きむら", "くらた", "ささき"]
import Foundation
//## トレイリング・クロージャ
//update: 16/06/15
//let lよみa = ["おおた", "くらた", "きむら", "ささき", "あいだ"]
var vよみa = ["おおた", "くらた", "きむら", "ささき", "あいだ"]
//update: 16/06/15
//func fクロージャを引数に持つ関数(closure: () -> Void) {
func fクロージャを引数に持つ関数(_ closure: () -> Void) {
//関数ボディ
}
// トレイリング・クロージャを使わずに関数を呼ぶ
fクロージャを引数に持つ関数({
//クロージャ・ボディ
})
// トレイリング・クロージャを使って関数を呼ぶ
// 要するに、クロージャ{} を () の外に出す
fクロージャを引数に持つ関数() {
//トレイリング・クロージャ・ボディ
}
//(--- Swift3 ---) update: 16/06/15
//var v逆順配列 = lよみa.sort({$0 > $1})
//(--- Swift3 beta6 ---) update: 16/08/18
//vよみa.sort(isOrderedBefore:{$0 > $1})
vよみa.sort(by:{$0 > $1})
print(vよみa) //結果:["ささき", "くらた", "きむら", "おおた", "あいだ"]
//(--- Swift3 ---) update: 16/06/15
//v逆順配列 = lよみa.sort() {$0 > $1} //トレイリング・クロージャの例
vよみa.sort() {$0 < $1} //トレイリング・クロージャの例(昇順)
print(vよみa) //結果:["あいだ", "おおた", "きむら", "くらた", "ささき"]
// トレイリング・クロージャのサンプル:
func f指定回数実行(回数: Int, クロージャ: ()->()) {
for _ in 0..<回数 {
クロージャ()
}
}
//(--- Swift3 ---) update: 16/06/15
//f指定回数実行(2) {
f指定回数実行(回数: 2) {
print("aaa")
}
/* 結果:
aaa
aaa
*/
import Foundation
//## クロージャを引数に持つ配列のメソッド
//# filter: [x1, .. , xn].filter(条件) -> [マッチ(xi), .. ]
let l偶数を選択 = [1, 2, 3, 4].filter { $0 % 2 == 0 }
print(l偶数を選択) //結果:[2, 4]
print(Array(0...13).filter {$0%2==0})
//結果:[0, 2, 4, 6, 8, 10, 12]
// フィルタの仕組み: 任意の型の配列の各要素をチェック関数で
// 調べてマッチするものを結果として返す
// func filter<T>(source: [T], checkfunc:(T)->Bool) -> [T]
// update: 16/06/15
//func fフィルタ<任意の型>(ソース配列: [任意の型],
func fフィルタ<任意の型>(_ ソース配列: [任意の型],
チェック関数:(任意の型) -> Bool) -> [任意の型] {
var 結果 = [任意の型]()
for 要素 in ソース配列 {
if チェック関数(要素) {
結果.append(要素)
}
}
return 結果
}
print( fフィルタ([1, 5, 6, 9, 12]) {$0%2==0} )
//結果:[6,12]
//# reduce: [x1, .. , xn].reduce(x, f) -> [f(x,x1)->x, .. f(x,xn)->x]
// func reduce<U>(initial:U, combine:(U,T)->U) -> U
let l最大値 = [3, 8, 1, 12, 5].reduce(3) {
// x と xi を比較して大きい方を次の x として返す
if $0 > $1 {
return $0
} else {
return $1
}
}
print(l最大値) //結果:12
//# reduce:
let l結合文字列 = ["a","b","c"].reduce("") {
// x が "" の時は xi を、それ以外は x + xi を次の x として返す
if $0 == "" {
return $1
} else {
return $0 + $1
}
}
print(l結合文字列) //結果: abc
//# redude:
let l整数合計 = Array(1...5).reduce(0) {
(合計, 整数) in 合計 + 整数
}
print(l整数合計) //結果:15
//# filter + reduce:
let l偶数合計 = Array(1...5)
.filter { (整数) in 整数 % 2 == 0 }
.reduce(0) { (合計, 整数) in 合計 + 整数 }
print(l偶数合計) //結果:6
//mapメソッドは配列の要素ごとに関数/クロージャを実行する
// [x1, .. , xn].map(f) -> [f(x1), .. , f(xn)]
let l漢数字 = [
0: "〇", 1: "一", 2: "二", 3: "三", 4: "四",
5: "五", 6: "六", 7: "七", 8: "八", 9: "九" ]
let l漢数字列 = [16,581,2703].map {
(配列の要素) -> String in
var v結果 = ""
//最初の要素の場合:v数値は 16
var v数値 = 配列の要素
while v数値 > 0 {
//## 値の取得:クロージャはその前後のコンテキストから
// 定数や変数を取得できる.
// クロージャ外部の l漢数字配列を使用
// v数値が 16 の場合、v数値 % 10は1の位の数 6
v結果 = l漢数字[v数値 % 10]! + v結果
// 10で割って10の位を1の位へ変更
v数値 /= 10
}
return v結果
}
print(l漢数字列) //["一六", "五八一", "二七〇三"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment