【发布时间】:2011-06-12 02:58:01
【问题描述】:
什么是 JS 的 map() 函数的 Objective-C 等价物?我可以只使用 NSFastEnumeration 并自己应用该函数吗?
【问题讨论】:
-
它内置在 Swift 中,距离您提出这个问题仅 3 年半。
标签: javascript objective-c porting
什么是 JS 的 map() 函数的 Objective-C 等价物?我可以只使用 NSFastEnumeration 并自己应用该函数吗?
【问题讨论】:
标签: javascript objective-c porting
如果您使用的是 OS X 10.6 或 iOS 4,则可以使用 NSArray 的 enumerateObjectsUsingBlock:。:
NSMutableArray *mapped = [NSMutableArray arrayWithCapacity:[array count]];
[array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id mapObj = DoSomethingToObject(obj);
[mapped addObject:mapObj];
}];
(无耻但相关的插件:我有一个用于 OS X 和 iOS 的 library,它为 NSArray 和 NSSet 添加了地图和其他类似功能。)
【讨论】:
这取决于。如果你有一个对象数组,并且这些对象有一个URL 属性(例如),那么你可以这样做:
NSArray * urls = [myArray valueForKey:@"URL"];
同样,如果您可以通过采用 0 或 1 个参数的单个消息触发相关对象的行为,您可以这样做:
[myArray makeObjectsPerformSelector:@selector(doFoo)];
//or:
[myArray makeObjectsPerformSelector:@selector(doFooWithBar:) withObject:aBar];
除此之外,您必须自己迭代对象。您可以使用for() 循环、for(in) 循环或-enumerateObjectsUsingBlock: 之类的东西。
【讨论】:
valueForKey: 也适用于 NSDictionary 数组。
你自己做。没有任何一种方法可以满足您的需求。
编辑:对于那些投反对票的人来说,这是当时(三年前)的正确答案,现在仍然适用于 Objective-C,但 Swift 确实有一个 map() 函数。
【讨论】:
查看BlocksKit,它为 NSArray 提供 map、reduce 和 filer。
- (NSArray *)map:(BKTransformBlock)block;
- (id)reduce:(id)initial withBlock:(BKAccumulationBlock)block;
- (NSArray *)select:(BKValidationBlock)block;
【讨论】:
NSArray的类别函数替代
- (NSArray *)map:(id(^)(id, BOOL *))block {
NSMutableArray * array = [NSMutableArray array];
[self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
id newObject = block(obj,stop);
if (newObject == nil) {
newObject = [NSNull null];
}
[array addObject:newObject];
}];
return array.copy;
}
NSMutableArray的类别函数替代
- (NSMutableArray *)map:(id(^)(id))block {
NSEnumerator * enumerator = ((NSArray *)self.copy).objectEnumerator;
id obj; NSUInteger idx = 0;
while ((obj = enumerator.nextObject)) {
self[idx] = block(obj) ?: [NSNull null];
idx++;
}
return self;
}
【讨论】: