SwiftのArrayクラスにはreverseメソッドがありますが、NSArrayには無いんですよね。 「関数型言語」と「手続き型+OOP言語」の文化的違いがよく現れていますね。
というわけで、NSArrayでReverse関数を実現する方法を紹介します。
一番シンプルな方法
NSArray.reverseObjectEnumerator経由で逆順配列を取得する方法です。
@[@"a", @"b"].reverseObjectEnumerator.allObjects; // ["b", "a"]
処理効率重視
もう一つはfor文で1つずつ可変配列に詰め込んでいく方法です。copyメソッドを呼び出さないという前提であれば、こちらの方法のほうが若干速いです。
@implementation NSArray (McLab)
- (NSMutableArray *)reverse {
NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.count];
for (id value in self.reverseObjectEnumerator) {
[array addObject:value];
}
return array;
}
@end
@[@"a", @"b"].reverse; // ["b", "a"]
Reverse関数の用途によってはイミュータブルの必要性は少ないため、あえてcopyを呼ばないようにしていますが、reverseメソッドの戻り値をモデル側でミュータブルとして保持する場合には注意しましょう。 copyメソッドを呼ぶか、先ほどのreverseObjectEnumeratorイディオムの利用をオススメします。
ベンチマーク
参考までに、それぞれのイディオムを100要素の配列で試した場合のベンチです。
ary.reverseObjectEnumerator.allObjects; // 0.000005sec
ary.reverse; // 0.000004sec
ary.reverse.copy; // 0.000006sec
私「Reverse無しの言語が許されるのは第二世代までだよね〜」
Objective-C「ぐぬぬ・・・」