#SwiftのカスタムクラスArrayでフィルター
SwiftのArray内に以下の様なクラスのオブジェクトが入っていたとして、プロパティの値でフィルターするときのメモ。
※末尾にNSPredicateでの記法も書いておきます。
(データベース的にコーディングするなら、機能が豊富なNSPredicateの方が楽かも)
##使用するカスタムクラス(!無しのプロパティに修正)
class Cat:NSObject{
var name:String
var color:String
var age:Int
var score:Int
init(data: (String,String,Int,Int)){
name = data.0
color = data.1
age = data.2
score = data.3
}
}
##テストデータ
テストデータを準備しておきます。
var all_cats:[Cat] = [Cat]()
all_cats.append(Cat(data:("タマ","白",10,10)))
all_cats.append(Cat(data:("コトロ","茶トラ",2,10)))
all_cats.append(Cat(data:("ミケ","三毛",3,10)))
all_cats.append(Cat(data:("チビトラ","茶トラ",4,10)))
all_cats.append(Cat(data:("タケチヨ","キジトラ",7,10)))
all_cats.append(Cat(data:("マリアンヌ","白",7,10)))
##フィルター処理
###正式な記法
まず、正式な記法だと以下のとおり。
var whitle_cats = all_cats.filter({
//filterメソッドは引数として配列内のオブジェクトを受け取れます
//また戻り値はBool型
(cat: Cat) -> Bool in
//フィルター結果として、残したい要素だけtrueを返す(検索条件)
return cat.color == "白"
})
結果を確認すると以下のとおり
for cat in whitle_cats{
println(cat.name + ":" + cat.color)
}
タマ:白
マリアンヌ:白
###※省略した記法
Swiftでは関数パラメータを渡すときに、引数の記述を省略して$0,$1として値を受け取ることができます。またreturn文を省略して直接処理結果をreturnすることができます。
var whitle_cats2
= all_cats.filter( { $0.color == "白" })
//結果確認
for cat in whitle_cats2{
println(cat.name + ":" + cat.color)
}
タマ:白
マリアンヌ:白
##Objective-Cと同様にNSPredicateを使う場合
NSPredicateはCoreDataなどでも利用されているように、非常に強力なパターンマッチングやグループ化の機能を持っています。Array内の抽出を行うならこちらを活用するのもありだと思います。(Swiftの配列上に同様の機能が盛り込まれるのかは不明であるため)
//検索条件をNSPredicateで作成
let pred:NSPredicate = NSPredicate(format: "color contains '茶'")!
//Swiftの配列にはNSPredicateを使うメソッドが無いため、NSArrayにキャストして呼び出す
let white_cats3 = (all_cats as NSArray).filteredArrayUsingPredicate(pred)
//結果確認
for cat in white_cats3{
println(cat.name + ":" + cat.color)
}
コトロ:茶トラ
チビトラ:茶トラ
※SwiftのArrayからNSArrayの変換をどうするのかと思いましたが、キャストだけで良いのは楽ですね!