やりたかったこと
ある関数にいくつかidのセット(id1,id2)を渡す。渡したもののうち、
下記のNSDictionayの配列に含まれる要素に一致したものを取り出したい。
- フィルタ用のデータ構造
これはAPIからJSONで取得され、NSDictionaryのNSArrayで格納している。
(
{
id1 = 4744139161607189037;
id2 = 288;
},
{
id1 = 4744139163368868020;
id2 = 288;
}
)
- サンプル関数 ※上記のNSArrayはdataという変数で表現
+(BOOL) sampleFunc:(NSString*) id1 id2:(NSString*) id2 {
NSString *query = [NSString stringWithFormat:@"id1 == %@ && id2 == %@", id1, id2]; //クエリ作成
NSPredicate *predicate = [NSPredicate predicateWithFormat:query]; //クエリをNSPredicateにする
NSArray *matched = [data filteredArrayUsingPredicate:predicate]; //predicateでフィルタリング
NSLog(@"%@",matched);
}
ハマり具合
- 実際に関数に渡していた引数のリスト(処理的には、リスト分だけ関数を呼んでいる)
4744139161607189037, 288
4744139163368868024, 288
4744139163368868020, 288
このとき、一致しないはずの4744139163368868024
,288
が一致扱いになっていた。
ここでデバッガでpo data
とかしてdataの中身を確認してみると..
(
{
id1 = "4.74413916160719e+18";
id2 = 288;
},
{
id1 = "4.744139163368868e+18";
id2 = 288;
}
)
あっ!丸められている!!
それで4744139163368868024
も4744139163368868020
も
同じ数字扱いになっていたのですね。
JSONで受け取っている関係で、2^53-1(2の53乗-1)以上の数字は丸められてしまいます。
なので、API側でid1の方は文字列として返さないといけないようです。これで勝てる!!
・・・
大丈夫じゃなかった。こんどは何も一致しない。
またAPIから受け取ったフィルタ用データを見てみる。
(
{
id1 = 4744139161607189037;
id2 = 288;
},
{
id1 = 4744139163368868020;
id2 = 288;
}
)
ちゃんと文字列になっている。じゃあフィルタ条件がおかしい?
+(BOOL) sampleFunc:(NSString*) id1 id2:(NSString*) id2 {
NSString *query = [NSString stringWithFormat:@"id1 == %@ && id2 == %@", id1, id2];
NSPredicate *predicate = [NSPredicate predicateWithFormat:query];
NSArray *matched = [data filteredArrayUsingPredicate:predicate]; //dataは上記のNSArray
NSLog(@"%@",matched);
}
うーむ。。あっ!
文字列にしたんだからこうじゃなくて
NSString *query = [NSString stringWithFormat:@"id1 == %@ && id2 == %@", id1, id2];
こうですね
NSString *query = [NSString stringWithFormat:@"id1 like \"%@\" && id2 == %@", id1, id2];
ちなみに比較演算子をlikeにしただけだと
'Can't create a regex expression from object 〜.'
とかいわれて怒られるので、プレースホルダ前後のダブルクォートは必須です。(これ気付くのも時間かかったorz)
おつかれさまでした