注意 - 使用可变参数, Phix 在下面提供了一个超级解决方案。但是,当它与整数一起使用时,它会给出编译器警告,因为你将它们转换为id,并且它不适用于例如浮点数。
问题 - 如何编写从列表中选择一个项目的设施?理想情况下,它会尽可能灵活地关于项目/对象的类型 /列表中的任何内容。
使用示例:
NSInteger openingMap = [utilities oneOf:1, 2, 3, 7, 8];
initialAngle =oneOf(1.25, 1.75, 1.95, 2.00, 2.01);
self.spaceShipNickName =oneOf(@"Blaster",@"Blitzen",@"Stardancer",@"Quantum");
self.chassisProperty = oneOf(titanium, neutronium, unavailablium);
[fireworksLayer paintStars:oneOf(blue,green,white) howMany:oneOf(20,25,50)];
[trump chooseDefaultSuite:oneOf(diamonds,hearts,clubs,spades)];
// normally have a few explosions, but, occasionally have a huge display...
explosionCount = oneOf( 2,2,2,3,4,1,28,3,3,3,70 );
请注意,一些示例是整数,一些枚举,一些NSStrings等。再次,如果一个工具可以处理不同类型,那将是最令人印象深刻的。 (而不是一个相关的组,比如...... oneOfIntegers,oneOfStrings,oneOfObject,等等。)
不用说,选择随机项目,只需使用...
= arcrandom()%number of of items
您可以使用 Objective C方法或类,c函数或某种宏系统,NSMutableArray的类别扩展,或者确实阻止 - 或其他任何内容。 它应该尽可能灵活,以便在典型的iOS或Mac项目的任何地方广泛使用......任何想法?
答案 0 :(得分:2)
我把它作为NSArray上的一个类别(警告 - 此代码未经测试,可能有一个错误!)
@interface NSArray (one_of)
- (id)anyObject;
@end
@implementation NSArray (one_of)
- (id)anyObject {
if (0 == [self count]) return nil;
if (1 == [self count]) return [self objectAtIndex:0];
return [self objectAtIndex:(arcrandom() % [self count])];
}
@end
然后,使用它:
NSString *thingy = [[NSArray arrayWithObjects:@"1", @"2", @"3"] anyObject];
NB要处理数字(以及其他原生类型等),你必须使它们成为对象,即
NSInteger number = [[[NSArray arrayWithObjects:
[NSNumber numberWithInteger:1],
[NSNumber numberWithInteger:2],
[NSNumber numberWithInteger:3], nil] anyObject] intValue];
答案 1 :(得分:2)
#define NUMARGS(...) (sizeof((id[]){__VA_ARGS__})/sizeof(id))
#define ONEOF(...) (oneOf(NUMARGS(__VA_ARGS__), __VA_ARGS__))
id oneOf(int numargs, ...) {
va_list ap;
va_start(ap,numargs);
int i = arc4random() % numargs;
id val = nil;
do {
val = va_arg(ap, id);
} while (i--);
va_end(ap);
return val;
}
用法:
NSLog(@"%@", ONEOF(@"Blaster",@"Blitzen",@"Stardancer",@"Quantum"));
NSLog(@"%d", ONEOF( 2,2,2,3,4,1,28,3,3,3,70 ));
请注意,两者都有效,但后者会抛出一些编译器警告。