クロージャを返す
CoddyのSwiftジャーニー「ロジックとフロー」セクションの一部 — レッスン 41/56。
makeCounter がクロージャを返すのを見ました。同じ手法を使って、設定可能な振る舞いを構築できます。一度パラメータを受け取り、それを何度も使用する関数を返します。
func multiplier(_ k: Int) -> (Int) -> Int {
return { n in n * k }
}
let triple = multiplier(3)
let tenfold = multiplier(10)
print(triple(4)) // 12
print(tenfold(4)) // 40返されるクロージャは k をキャプチャするため、各 multiplier(...) の呼び出しは、独自の k を持つまったく新しいクロージャを生成します。
このパターンは、Swiftにおける「ストラテジー」コードの核心です。設定を受け取りクロージャを返す関数を記述し、そのクロージャを map、filter、sorted(by:)、または関数型の値が期待されるその他の場所に渡します。
チャレンジ
中級2つのクロージャファクトリを作成してください:
greaterThan(_ k: Int) -> (Int) -> Bool: 引数がkより大きい場合にtrueを返す述語を返します。scaleBy(_ k: Int) -> (Int) -> Int: 引数にkを掛ける関数を返します。
以下の3行を読み込んでください:
- 整数
threshold - 整数
scale - カンマ区切りの整数リスト
nums
以下の3行を出力してください:
- しきい値(threshold)を超える数値(
greaterThanからのクロージャでフィルタリングしたもの)を,で連結したもの - 同じ数値をスケール(
scaleByでマップしたもの)し、,で連結したもの - 条件を満たした数値の個数
入力が 5 / 3 / 2,7,3,8,9 の場合、出力は以下のようになります:
7,8,9
21,24,27
3自分で試してみよう
let threshold = Int(readLine()!)!
let scale = Int(readLine()!)!
let nums = readLine()!.components(separatedBy: ",").map { Int($0)! }
// TODO: greaterThan, scaleBy; フィルタリングしてからマッピング; 結合して出力し、カウントを表示
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。