0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Objective-Cのダサい配列操作をわりかしまともにする

Last updated at Posted at 2020-10-19

Objective-Cしんどい

大昔Objective-Cはサイコーだと思ってた時期はあったが、近代的な言語に触れてからだとだいぶ冗長でしんどく感じるObjective-C。
Objective-CとSwiftが混ざっているプロジェクトを触る必要があって、せめてよく使う配列操作だけでもなんとかしようと工夫してみた。

# import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface NSArray<__covariant ObjectType> (Functional)

@property(nonnull, readonly) void (^forEach)(void(^)(ObjectType _Nonnull object));
@property(nonnull, readonly) NSArray<ObjectType>* _Nonnull (^filter)(BOOL(^)(ObjectType _Nonnull object));
@property(nonnull, readonly) NSArray<id>* _Nonnull (^map)(id(^)(ObjectType _Nonnull object));
@property(nonnull, readonly) NSArray<id>* _Nonnull (^flatMap)(NSArray<id>* _Nonnull (^)(ObjectType _Nonnull object));
@property(nonnull, readonly) id (^reduce)(id initialValue, id (^)(id accum, ObjectType _Nonnull object));

@end

NS_ASSUME_NONNULL_END
@implementation NSArray (Functional)

-(void (^)(void (^ _Nonnull)(id _Nonnull)))forEach {
	return ^(void(^block)(id)) {
		for(id elem in self) block(elem);
	};
}

-(NSArray<id>* _Nonnull (^)(BOOL (^ _Nonnull)(id _Nonnull)))filter {
	return ^(BOOL (^blk)(id)) {
		NSMutableArray<id> *arr = NSMutableArray.array;
		for(id elem in self) if(blk(elem)) [arr addObject: elem];
		return arr;
	};
}

-(NSArray<id> * _Nonnull (^)(id (^ _Nonnull)(id _Nonnull)))map {
	return ^(id(^blk)(id)) {
		NSMutableArray<id> *arr = NSMutableArray.array;
		for(id elem in self) [arr addObject: blk(elem)];
		return arr;
	};
}

-(NSArray<id> * _Nonnull (^)(NSArray<id> * _Nonnull (^ _Nonnull)(id _Nonnull)))flatMap {
	return ^(NSArray<id>*(^blk)(id)) {
		NSMutableArray<id> *arr = NSMutableArray.array;
		for(id elem in self) [arr addObjectsFromArray: blk(elem)];
		return arr;
	};
}

-(id (^)(id, id (^ _Nonnull)(id, id _Nonnull)))reduce {
	return ^(id initialValue, id (^blk)(id, id)) {
		id accum = initialValue;
		for(id elem in self) accum = blk(accum, elem);
		return accum;
	};
}

@end

動くか確かめる

+(void)test {
	NSArray<NSNumber *>* array = @[@1, @2, @3, @4, @5, @6];
	id a = array.map(^id(NSNumber *  _Nonnull object) {
		return @(object.intValue * 2);
	});
	
	id b = array.filter(^BOOL(NSNumber* _Nonnull object) {
		return object.intValue % 2 == 0;
	});
	
	id c = array.flatMap(^NSArray<id> * _Nonnull(NSNumber* _Nonnull object) {
		return @[object, object];
	});
	
	id d = array.reduce(@0, ^id _Nonnull(NSNumber* _Nonnull accum, NSNumber* _Nonnull object) {
		return @(accum.intValue + object.intValue);
	});
	
	NSLog(@"%@", a);
	NSLog(@"%@", b);
	NSLog(@"%@", c);
	NSLog(@"%@", d);
}
出力
2020-10-19 22:34:31.161505+0900 Objective-C Hacks[37672:1250661] (
    2,
    4,
    6,
    8,
    10,
    12
)
2020-10-19 22:34:31.161649+0900 Objective-C Hacks[37672:1250661] (
    2,
    4,
    6
)
2020-10-19 22:34:31.161797+0900 Objective-C Hacks[37672:1250661] (
    1,
    1,
    2,
    2,
    3,
    3,
    4,
    4,
    5,
    5,
    6,
    6
)
2020-10-19 22:34:31.161942+0900 Objective-C Hacks[37672:1250661] 21

まだ極めてイケてない

これがObjective-Cの限界か?
マクロとかゴリゴリ悪用したらもっとよくならないかな。
それから配列にオブジェクトしか入らない粗末な仕様だからNSNumber入れたり出したりがダサさを際立たせてる。

こうしてみるとSwiftの型推論だとかクロージャとかがマジで記述量減らしてくれて楽。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?