reduceで配列のサブクラス確認
ある型を継承したインスタンスの配列を作ったときに親クラスが同じなら、サブクラスの型は違っても配列を作ることができます。
let anyArray :[Any] = [1, 2.2, "hello"]
このとき、特定のサブクラスが入っているかどうかを判定するのにreduceが便利だなと思ったのでメモします。
let anyArray :[Any] = [1, 2.2, "hello"]
let isExitString = anyArray.reduce(false, {
flg, value in
switch flg {
case true :
return flg
case false :
return value is String
}
})
print(isExitString)//->true
解説
SwiftのArray型のメソッドreduceを使うと配列の要素を畳み込むことができます。
第一引数を初期値に第二引数のクロージャーで各要素の処理を書きます。
クロージャーのキャプチャリストに今までの処理の結果と、要素の値が入ります。
クロージャー処理に判別したいサブクラスの型を判定する処理を書けば、配列の要素にそのサブクラスがある配列かどうかを確認することができます。
各イテレーションのflgとvalueとresultは以下のようになります
iteration | flg: U | value: T | result |
---|---|---|---|
1 | false | 1 | false |
2 | false | 2.2 | false |
3 | false | "hello" | true |
実践編
iOSのプッシュ通知でAppDelegateでアプリビューを特定のビューで表示したかったのです。
ビューはナビゲーションバーで管理しているのですが、メイン画面、設定画面がスタックされて、設定画面の上にさまざまな各設定詳細画面が乗っているという状態です。
で、設定詳細画面が表示されていたら設定画面まで戻るということをしたいと思っていました。
その判定をreduceで書いてみると以下のようになると思います。
///実際にやりたかったこと
class MainViewCon :UIViewController {}
class SettingViewCon:UIViewController{}
class SettingDetailCon1:UIViewController{}
let mainViewCon = MainViewCon()
let settingViewCon = SettingViewCon()
let settingDetailCon1 = SettingDetailCon1()//SettingDetailCon2, SettingDetailCon3などいろいろな設定詳細画面がある
let navi = UINavigationController()
navi.addChildViewController(mainViewCon)
navi.addChildViewController(settingViewCon)
navi.addChildViewController(settingDetailCon1)
//
let isSecond = navi.childViewControllers.reduce(false, {
flg, viewController in
switch flg {
case true:
return flg
case false:
return viewController is SettingViewCon
}
})
if isSecond && navi.childViewControllers.count >= 2 {
//設定詳細画面を表示しているなら設定画面に戻る
navi.popToViewController(settingViewCon, animated: true)
}
おわりに
reduceで検索すると数値の合計がよくサンプルコードででてくるんですが、配列の要素の型調べでも使えるかと思い記事にしました。
皆さんのお役に立てれば幸いです。