MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

swiftで関数型プログラミングのススメを受けた話

前回移動した画像がどの場所にいるかを表示するアプリを作成しました。
その後、以前参加させて頂ましたiPhoneアプリ開発キャンプの講師でありますアキオさん(@akio0911)よりコメント頂きました。初めてのgithubのpull requestに興奮です!

内容としては、「ここの部分、もっと短くシンプルに書けるよ。そうswiftならね。」というものです。

以下のgithubのdiffを参照お願いします。

github.com

上記をマージ後のgithubは以下です。

github.com

自分ポイント1

私はタッチ完了時に一番近いlocationViewの判別・保存を以下のようにgetDistance()というメソッドを新規作成して実現していました。

    //各locationとの距離とその最小値のIndexを保存するメソッド
    func getDistance() -> distanceClass {
        let distance: distanceClass = distanceClass()
        
       for (index, val) in enumerate(locationLabelArray) {
           distance.distanceArray.append(getDistanceWithPoint1(imageBeHereNow.center, point2: locationLabelArray[index].center))
           
           if distance.distanceArray[index] == minElement(distance.distanceArray) {
               distance.minIndex = index
           } else {
               //Do nothing
           }
           
       }

        return distance
    }
    
    
    //2点の座標間の距離を取得するメソッド
    func getDistanceWithPoint1(point1: CGPoint, point2: CGPoint) -> CGFloat {
        let distanceX = point1.x - point2.x
        let distanceY = point1.y - point2.y
        let distance = sqrt(distanceX * distanceX + distanceY * distanceY)
        return distance
    }

pull requestの内容を確認しますと、getDistance()内のfor文の部分について、swiftの配列用のメソッド(なのか?)、map, reduceを使って、かなりシンプルに変更されておりました。

    //各locationとの距離とその最小値のIndexを保存するメソッド
    func getDistance() -> distanceClass {
        let distance: distanceClass = distanceClass()
        
        distance.distanceArray = locationLabelArray.map({self.getDistanceWithPoint1(self.imageBeHereNow.center, point2: $0.center)})
        let (index, _) = reduce(enumerate(distance.distanceArray), (-1, CGFloat(FLT_MAX))) {
            $0.1 < $1.1 ? $0 : $1
        }
        distance.minIndex = index

        return distance
    }
    
    
    //2点の座標間の距離を取得するメソッド
    func getDistanceWithPoint1(point1: CGPoint, point2: CGPoint) -> CGFloat {
        let distanceX = point1.x - point2.x
        let distanceY = point1.y - point2.y
        let distance = sqrt(distanceX * distanceX + distanceY * distanceY)
        return distance
    }

map, reduceについては以下のページで理解ができました。

qiita.com

こうゆうのを「関数型プログラミング」っていうのだと思います。
かなりかっこいい書き方なので「使える」タイミングを見つけたらどんどん使っていきたいと思います。