I have an array with a bunch of NSNumbers. From an UISlider I get a certain value when the user stops dragging it. I would like to get the closes number from the array.
So for instance, if the user drags the UISlider to 13, and the NSArray contains the NSNumbers with 10 and 15; I want to get 15 from the array.
Example of array:
NSArray *values = [NSArray arrayWithObjects:[NSNumber numberWithInt:15],
[NSNumber numberWithInt:20],
[NSNumber numberWithInt:30],
[NSNumber numberWithInt:45],
[NSNumber numberWithInt:60],
[NSNumber numberWithInt:90],
[NSNumber numberWithInt:110], nil];
How do I get the correct number from the array?
In your post, the array is sorted. If it's always sorted, you can use binary search. NSArray has a convenient method for that:
CGFloat targetNumber = mySlider.value;
NSUInteger index = [values indexOfObject:@(targetNumber)
inSortedRange:NSMakeRange(0, values.count)
options:NSBinarySearchingFirstEqual | NSBinarySearchingInsertionIndex
usingComparator:^(id a, id b) {
return [a compare:b];
}];
Now there are four possibilities:
- Every element of
valuesis larger thantargetNumber:indexis zero. - Every element of
valuesis smaller thantargetNumber:indexisvalues.count. valuescontainstargetNumber:indexis the index oftargetNumberinvalues.indexis the index of the smallest element ofvaluesthat is greater thantargetNumber.
I've cleverly listed the cases in the order we'll handle them. Here's case 1:
if (index == 0) {
return [values[0] floatValue];
}
Here's case 2:
if (index == values.count) {
return [[values lastObject] floatValue];
}
We can handle cases 3 and 4 together:
CGFloat leftDifference = targetNumber - [values[index - 1] floatValue];
CGFloat rightDifference = [values[index] floatValue] - targetNumber;
if (leftDifference < rightDifference) {
--index;
}
return [values[index] floatValue];
If your values array is in order and you always want the value just larger than (or equal to) the entered value you could do something like this:
NSInteger count = 0;
do {
count++;
} while (enteredNum > [values[count] intValue]);
// Do something with [values[count] intValue]
来源:https://stackoverflow.com/questions/14086770/pick-closest-nsnumber-from-array