NSArrayな配列を逆順にreverseする色々な方法


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「ぐぬぬ・・・」

広告