Reputation: 336
We have a Dictionary with the following structure:
_availableCharacterClasses = [[NSMutableDictionary alloc] init];
[_availableCharacterClasses setObject:[NSNumber numberWithFloat:[DefaultNova characterSpawnProbability]] forKey:NSStringFromClass([DefaultNova class])];
where probability has a value between 0 (low) and 100 (height)
now i want to pick a random key (weighted) from the _availableCharacterClasses-Dictionary.
How can i archive this using objective c?
Upvotes: 0
Views: 596
Reputation: 494
If you want to pick random key for given value you can do something like:
float value = 3;
NSArray * keys = [_availableCharacterClasses.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@[self].floatValue == %f", _availableCharacterClasses, value]];
NSString *anykey = keys[arc4random_uniform(keys.count)];
Upvotes: 0
Reputation: 2842
Ah I think now I've got your question correct. I assume the probabilities sum up to 100?
int random = arc4random%100;
NSArray *probabilities = [_availableCharacterClasses allObjects];
NSArray *keys = [_availableCharacterClasses allKeys];
CGFloat currentValue = 0;
int index=0;
for(NSNumber *p in probabilities){
currentValue+=[p floatValue];
if(random<currentValue){
//found now get the key
return keys[index];
}
index++;
}
Upvotes: 1
Reputation: 336
@Robert i have modified your solution slightly and came up with the following result
- (NSUInteger)randomIndexByProbability:(NSArray *)probabilities
{
CGFloat randomNumber= arc4random_uniform(100) + (float)arc4random_uniform(101)/100;
NSUInteger weightedIndex = 0;
CGFloat totalProbability = 0.0;
for(NSUInteger i=0; i<probabilities.count; i++)
{
totalProbability += [probabilities[i] floatValue];
if(totalProbability >= randomNumber)
{
break;
}
weightedIndex++;
}
return weightedIndex;
}
Upvotes: 0