見出し画像

楽しい!Swift。 - A Swift Tour (Functions and Closures-2)

関数の中に関数を入れることができます。関数内に新たに関数を定義することで関数内の範囲で変数が使えたり、必要な項目に対して整理して構築することができます。

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
}
returnFifteen()

次です。関数は他の関数を戻り値にすることができます。

((Int) -> Int)  ・・・ 関数を表します。

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

これを実行すると返り値の指定されている

return addOne

の通り

func addOne(number: Int) -> Int {
  return 1 + number
}

が実行され"8"となります。

さらに、引数についても関数を使うことができます。

(list: [Int], condition: (Int) -> Bool) ・・・ 太字が関数

func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
    for item in list {
        if condition(item) {
            return true
        }
    }
    return false
}

使う引数は

別に関数を定義します。

func lessThanTen(number: Int) -> Bool {
    return number < 10
}

変数も定義します。

var numbers = [20, 19, 7, 12]

実行は


hasAnyMatches(list: numbers, condition: lessThanTen)

とすると

return number < 10

であれば"true"となります。実行の状況をみてみます。

SwiftPlaygroundsでコードをステップ実行

"7"で10以下となるのでそのタイミングで"true"となります。

次はクロージャ(closures)です。頭に"func"、"名前"をつけなくても実行できるものができます。代わりに、"{ }""in"を使っています。以下例示です(参考ページのものを実行できるように追加しています)。

var numbers = [20, 19, 7, 12]

var n = numbers.map({ (number: Int) -> Int in
    let result = 3 * number
    return result
})

print(n)

[60, 57, 21, 36]

と配列の要素をそれぞれ3倍されたものが出力されます。"map"はそれぞれの要素に何かしら処理する場合に使うことができます。

これをもう少し簡単に書くこともできます。

let mappedNumbers = numbers.map({ number in 3 * number })
print(mappedNumbers)
// Prints "[60, 57, 21, 36]"

引数の型、戻り値の型、returnを省略できます。

mapではnumberに配列の要素を入れて処理していきますが、これを"$0"のように要素を表すことで下記のように要素どうしを比較することもできます。

let sortedNumbers = numbers.sorted { $0 > $1 }
print(sortedNumbers)
// Prints "[20, 19, 12, 7]"

"sorted"を使って"$0 > $1"を指定しているので大きな数値が前に行くように並び替えされています。


この記事が気に入ったらサポートをしてみませんか?