マニアックなライブラリを見つけたのでメモっておきます!

_.m Home

Underscore.js風のインターフェースを提供するObjective-Cのライブラリです。前書いたこれに少しだけ近い。

ActiveRecordのようなselectやwhereをObjective-Cで使う - ぴよログ

今回紹介する_.mにはmapとかreduceみたいなものもあるので、より関数型っぽい?んじゃないかと思います。Underscore.jsなどを知っている人には無用だけど、提供されているインターフェースについてざっくりと紹介。

each

1_.each(AI(1, 2, 3), ^(N* num, ...){ SS.alert(num); });
2// => alerts each number in turn...
3
4_.each(OKV({@"one", N.I(1)}, {@"two", N.I(2)}, {@"three", N.I(3)}), ^(N* num, ...){ SS.alert(num); });
5// => alerts each number in turn...

eachは各要素に特定の処理をさせるメソッドで、ループの代わりに使ったりします。まあ普通のeachってことです。

よく見るとAIとかOKVとかNといった謎のキーワードがでてきます。これは同じ人が書いたライブラリSubjectiveScriptで定義されているマクロで、こんな感じになっています。

1#define AI(...)   A.newI((I[]){__VA_ARGS__},    sizeof((I[]){__VA_ARGS__})/sizeof(I))
2#define OKV(...)        O.newWithKV((KV[]){__VA_ARGS__, /* NIL_TERMINATION */ nil})

ここでもAとかOとか色々略しまくっていてわかりにくいんですが、慣れた人に楽にかけるようにしたいって思想なんでしょうか。このライブラリについては最後に参考リンクと一部の定義を載せておきます。

map

各要素の対する処理結果を配列で得る場合に使うmap関数。

1_.map(AI(1, 2, 3), ^(N* num, ...){ return N.I(num.I * 3); });
2// => [3, 6, 9]
3_.map(OKV({@"one", N.I(1)}, {@"two", N.I(2)}, {@"three", N.I(3)}), ^id(N* num, ...){ return N.I(num.I * 3); });
4// => [3, 6, 9]

ここはAIやらOKVなどの略語がわかりさえすれば読めそうです。

reduce

コレクションの中身を集約するときに使うreduceです。初期値を与えてそれに対して各要素を使った値を足したりしていく感じ。Rubyではinject

1N* sum = _.reduce(AI(1, 2, 3), ^(N* memo, N* num, ...){ return N.I(memo.I + num.I); }, N.I(0));
2// => 6

delay

配列やディクショナリのようなコレクション要素に対する操作以外のこともできるようです。例えばdelayではNミリ秒後に実行させたい処理を簡単に書くことができます。

1_.delay(^{ NSLog(@"%d", 1000); }, NSEC_PER_SEC*1);
2// => 'logged later' // Appears after one second.

書き切れない

Underscore.jsにあるようなインターフェースのうちの8割〜9割ほどが提供されている感じです。公式のリファレンスが参考になりますが、Underscore.jsのリファレンスを読むのも助けになりそうです。

日本語の場合はこういうまとめが参考になりそう。

便利機能満載のライブラリUnderscore.js - にのせき日記便利機能満載のライブラリUnderscore.js - にのせき日記はてなブックマーク - 便利機能満載のライブラリUnderscore.js - にのせき日記

SubjectiveScript

kmalakoff/SubjectiveScript.m

 1typedef BOOL            B;
 2typedef NSInteger       I;
 3typedef NSUInteger      UI;
 4typedef float           F;
 5typedef double          D;
 6typedef id              KV[2]; // key-value pair
 7
 8#define NSO             NSObject
 9#define A               NSMutableArray
10#define NSA             NSArray
11#define O               NSMutableDictionary
12#define NSD             NSDictionary
13#define S               NSMutableString
14#define NSS             NSString
15#define Date            NSDate
16#define N               NSNumber
17#define E               NSException