黒龍's Blog

明日から役立つ無駄知識をあなたに(仮)

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  170  : 記事  0  : コメント  2707  : トラックバック  26

ニュース

わんくま同盟に参加させていただきました。
どうぞよろしくお願いします。

自己紹介

コミュニティ

  • わんくま同盟
    わんくま同盟

書庫

Objective-C Advent Calendar 2012の12/11の記事です。

最近どの言語でもシーケンスに対する処理ライブラリが充実しています。Objective-Cにも列挙や列挙を行うための仕組みも用意されているので.netと同じようなアプローチでLinq的なメソッドを実装してみました。

 

Linqって?

.netが持っているコレクションに対する操作をSQLチックに書けるコンパイラサポートの事なんですがここではコレクションに対する一連の操作メソッドという広義のLinqの方を取り上げます。

で、何が出来るかというとシーケンスに対するフィルタや変換、処理適用なんかがループ的な構文を使用する事なく記述できます。

例としてあるNSArrayからNSStringのものだけをNSArrayにするケースを考えてみます。

まぁ普通に考えると列挙して新しい配列に足し込んでってのが思いつきます。こんな感じに

    NSMutableArray *stringArray = [[NSMutableArray alloc]init];
    NSMutableArray *result = [[NSMutableArray alloc]init];
    for (id obj in [stringArray objectEnumerator]) {
        if ([obj isKindOfClass:[NSString class]]) {
            [result addObject:obj];
        }
    }
    return [NSArray arrayWithArray:result];

特に難しい事もないと思います。で、これをここで公開しているLinq for Objective-C(以下Linq)で書くとこんな感じ

     return [[[stringArray objectEnumerator]ofClass:[NSString class]]toArray];

ずいぶんとすっきりしたと思います。

他にもフィルタをかけるwhere、変換を行うselectなんかがあります。ありそうな例としてNSDictionaryとして受信したjsonがあったとします。それをフィルタをかけながら独自型に変換するようなイメージで書くと…

   NSArray *shops = [json objectForKey:@"shops"];
    return [[[shops objectEnumerator]
             select:^id(id shop) {
                 NSDictionary *shopDic = shop;
                 ShopData *result = [[ShopData alloc]init];
                 result.id = [json objectForKey:@"id"];
                 result.name = [json objectForKey:@"name"];
                 result.genre = [json objectForKey:@"genre"];
                 result.coordinate = CLLocationCoordinate2DMake([[json objectForKey:@"latitude"] doubleValue], [[json objectForKey:@"longitude"] doubleValue]);
                 result.image_url = [json objectForKey:@"image_url"];
                 return result;
             }]where:^BOOL(id item) {
                 return [(ShopData *)shop.genre isEqual:@"イタリアン"];
             }]toArray];

こんな感じになります。

まぁほとんど変換の部分が冗長なのでinitWithJSON:(NSDictionary*)json見たいなメソッドを作ってやればすっきりすると思います。

他にもいろいろなメソッドの組み合わせでフィルタをかける事が出来ますが冗長になってしまう場合や処理を自分で書きたい場合はCustomEnumeratorという列挙処理のヘルパがありますので処理をブロックで渡す事で独自の列挙処理を行う事が出来ます。

改行コードで一行ずつ取り出す例。マルチパートヘッダなど一気にNSStringに出来ないようなケースもあると思います。その場合はNSDataを直で列挙するobjectEnumeratorもカテゴリで追加しているのでcharでの処理も可能です。

- (NSEnumerator *)headers:(NSEnumerator *)src {
    return [[CustomEnumerator alloc]initWithFunction:src nextObjectBlock:^id(NSEnumerator *_src) {
        NSData * headData = [[_src takeWhile:^BOOL(id charNum) {
            
            char charByte = [( NSNumber*)charNum charValue];
            return (charByte != '\r');
        }]
                             toData];
        //最後まで読んでいるかチェックする。
        if ([[_src take:1]singleOrNil] == nil){
            //改行なく最後まで読んでいる場合は今回の解析は見送る。
            //バッファに今のデータを追加する。
            bufferData = [[NSMutableData alloc]initWithData:headData];
            return nil;
        }
        return [[NSString alloc]initWithData:headData encoding:NSUTF8StringEncoding];
    }];   
}

これらの処理メソッドですがもう一つの特徴として遅延処理があげられます。どういう事かというとフィルタや選択の各種メソッドは呼んだだけでは処理が登録されるのみで最終的にforinで列挙する際やtoXXXメソッドで変換する際に処理される事になります。

(toArray、toMutableArray、toDictionary、toMutableDictionary、toData、toStringなどいろいろな処理があります)

なので通常こういった処理を分割した際にありがちなバッファのコピーが余計に発生する事はないためメモリには優しい処理となる可能性もあります。 色々とメソッドがあってややこしいですがネットでもいろんな言語でシーケンス処理の例はありますのでそれらの処理をうまくObjective-Cに持って来れると思います。

また、ちょっとしたループ処理でも書けばバグの可能性は出てくるのでやりたい処理に注力できるこういったシーケンス処理ライブラリをぜひ使ってみませんか?(と、宣伝で締めてみる)

それでわ~

投稿日時 : 2012年12月10日 15:00

コメント

# ?????????????????????Advent Calender 2012?????????????????????????????????????????? « shobomalog 2012/12/26 19:53 Pingback/TrackBack
?????????????????????Advent Calender 2012?????????????????????????????????????????? « shobomalog

# EOOmHAbsCCRqF 2021/07/03 1:43 http://www.kss.edu.zm/members/kathysandoval/
Informative and precise Its hard to find informative and precise info but here I found

# mVOAXxjsiyCgBZeQXlt 2021/07/03 3:11 https://amzn.to/365xyVY
Thanks again for the blog.Thanks Again. Much obliged.

I view something really special in this site.

# re: Linq for Objective-C??????????? 2021/08/07 3:27 hydroxy chloroquine
premature babies wikipedia https://chloroquineorigin.com/# hydroxychloroquinone

# stromectol ireland 2021/09/28 20:36 MarvinLic
cost of ivermectin https://stromectolfive.com/# buy stromectol canada

# ivermectin australia 2021/11/03 11:38 DelbertBup
ivermectin price canada http://stromectolivermectin19.com/# stromectol ivermectin tablets
ivermectin lotion cost

# generic ivermectin for humans 2021/11/04 5:24 DelbertBup
ivermectin new zealand https://stromectolivermectin19.com/# ivermectin cost
ivermectin 4

# sildenafil 20 mg tablet uses http://viasild24.online/
2021/12/07 19:28 Nyusjdh
sildenafil 20 mg tablet uses http://viasild24.online/


# bimatoprost generic best price 2021/12/14 9:44 Travislyday
http://bimatoprostrx.online/ careprost bimatoprost ophthalmic best price

# best place to buy careprost 2021/12/15 22:42 Travislyday
http://stromectols.com/ ivermectin pills

# ivermectin eye drops 2021/12/17 15:13 Eliastib
oxocht https://stromectolr.com ivermectin 1% cream generic

# doxycycline 150 mg https://doxycyline1st.com/
generic for doxycycline 2022/02/26 8:26 Jusidkid
doxycycline 150 mg https://doxycyline1st.com/
generic for doxycycline

# GwquVCUSYrzSEQMV 2022/04/19 13:32 johnanz
http://imrdsoacha.gov.co/silvitra-120mg-qrms

# gates of olympus oyna ücretsiz - https://gatesofolympus.auction/ gates of olympus demo türkçe oyna 2024/03/27 21:12 Olympic
gates of olympus oyna ücretsiz - https://gatesofolympus.auction/ gates of olympus demo türkçe oyna

Post Feedback

タイトル
名前
Url:
コメント