Ruby 語言的 Array 類別有一個 map 方法,可以把一個 Block 應用到 Array 裡的每個元素上,並將 Block 的傳回值收集成一個新的 Array,例如:
a = ['a', 'b', 'c']
a.map {|e| e.upcase} # => ['A', 'B', 'C']
在 Objective-C 裡可以利用 GCD 的 dispatch_apply 函數來實現 map 方法:
#import <Foundation/Foundation.h>
@interface NSArray (RAMethods)
- (NSArray *)map:(id (^)(id item))block;
@end
#import "NSArray+RAMethods.h"
@implementation NSArray (RAMethods)
- (NSArray *)map:(id (^)(id item))block {
NSMutableArray *results = [NSMutableArray array];
for (int i = 0; i < self.count; ++i) {
[results addObject:[NSNull null]];
}
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(self.count, queue, ^(size_t index) {
[results replaceObjectAtIndex:index withObject:block([self objectAtIndex:index])];
});
return results;
}
@end
使用方式:
#import "NSArray+RAMethods.h"
...
NSArray *array = @[@"a", @"b", @"c", @"d", @"e"];
NSArray *tmpArray = [array map:^(id item) {
NSLog(@"%@", item);
return [item uppercaseString];
}];
NSLog(@"----------");
NSLog(@"tmpArray: %@", tmpArray);
輸出的結果:
a
c
d
e
b
----------
tmpArray: (
A,
B,
C,
D,
E
)
dispatch_apply 函數有三個參數:第一個參數是迭代次數,第二個參數是要使用的 Dispatch Queue ,第三個參數是要執行的 Block。
可以注意到在輸出結果中,虛線上方的字母次序跟 array 裡的次序不同,這是因為 dispatch_apply 函數會把第三個參數的 Block 加到 Dispatch Queue 裡,各個 Block 的執行時間不定,所以虛線上方的字母次序才會跟 array 裡的不同。